内联表单集工厂更新视图 [英] inline formset factory update view

查看:61
本文介绍了内联表单集工厂更新视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果要联系1个以上的联系人,我希望在更新视图 extra = 0 中插入内嵌表单工厂。所以这是我的代码

i want to get in inline formset factory in update view extra=0, if it have more than 1 contact. So this is my code

forms.py

class ShopForm(ModelForm):
    class Meta:
        model = Shop
        exclude = ['user', 'slug', 'counter']

    def __init__(self, *args, **kwargs):
       super(ShopForm, self).__init__(*args, **kwargs)
       for field in iter(self.fields):
           self.fields[field].widget.attrs.update({
            'class': 'form-control'
           })

    def clean_logo(self):
       logo = self.cleaned_data['logo']
       if not logo:
          raise forms.ValidationError("Логотип обязателен для заполнения", code='no_logo')
       return logo

    ShopInlineFormSet = inlineformset_factory(Shop, Contacts, extra=1,
                                      fields=(
                                          'published', 'phone', 'address', 'place', 'latitude',
                                          'longitude', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday',
                                          'saturday', 'sunday'), can_delete=True)

models.py

models.py

class Shop(PublishBaseModel, Counter):
    class Meta:
        verbose_name = 'Магазин'
        verbose_name_plural = 'Магазины'

    user = models.ManyToManyField(to=User, verbose_name='Администратор магазина')
    title = models.CharField(max_length=255, verbose_name='Название магазина')
    slug = models.CharField(max_length=32, verbose_name='Название на транслите', unique=True)
    email = models.EmailField(verbose_name='E-mail магазина')
    short_description = models.TextField(verbose_name='Короткое описание магазина')
    description = models.TextField(verbose_name='Полное описание магазина')
    logo = models.ImageField(upload_to='images/shop/logo/', default=settings.DEFAULT_IMAGE,
                             verbose_name='Логотип')

class Contacts(PublishBaseModel):
    class Meta:
        verbose_name = 'Контакт'
        verbose_name_plural = 'Контакты'

    address = models.CharField(verbose_name='Адрес', max_length=255, null=True, blank=True)
    phone = models.CharField(max_length=255, verbose_name='Телефон', null=True, blank=True)
    shop = models.ForeignKey(Shop, verbose_name='Магазин', null=True)
    place = models.ForeignKey('Place', verbose_name='Торговая точка', null=True, blank=True)
    latitude = models.CharField(max_length=255, verbose_name='Широта', null=True, blank=True)
    longitude = models.CharField(max_length=255, verbose_name='Долгота', null=True, blank=True)
    monday = models.CharField(max_length=255, verbose_name='Понедельник', null=True, blank=True)
    tuesday = models.CharField(max_length=255, verbose_name='Понедельник', null=True, blank=True)
    wednesday = models.CharField(max_length=255, verbose_name='Понедельник', null=True, blank=True)
    thursday = models.CharField(max_length=255, verbose_name='Понедельник', null=True, blank=True)
    friday = models.CharField(max_length=255, verbose_name='Понедельник', null=True, blank=True)
    saturday = models.CharField(max_length=255, verbose_name='Понедельник', null=True, blank=True)
    sunday = models.CharField(max_length=255, verbose_name='Понедельник', null=True, blank=True)

views.py

class ShopCreateView(LoginRequiredMixin, FormsetMixin, CreateView):
    form_class = ShopForm
    formset_class = ShopInlineFormSet
    model = Shop
    template_name = 'shop/shop_form.html'

    def get_success_url(self):
        return reverse('shops:detail', args=(self.object.slug,))

    def form_valid(self, form, formset):
        random_int = random.randrange(0, 1010)
        form.instance.slug = slugify(form.instance.title) + str(random_int)
        self.object = form.save()
        form.instance.user.add(self.request.user)
        formset.instance = self.object
        formset.save()
        return super(ShopCreateView, self).form_valid(form, formset)

class ShopUpdateView(LoginRequiredMixin, FormsetMixin, ShopMixin, UpdateView):
    model = Shop
    is_update_view = True
    form_class = ShopForm
    formset_class = ShopInlineFormSet
    template_name = 'shop/shop_update.html'

mixin.py

class FormsetMixin(object):
    object = None

    def get(self, request, *args, **kwargs):
        if getattr(self, 'is_update_view', False):
            self.object = self.get_object()
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        formset_class = self.get_formset_class()
        formset = self.get_formset(formset_class)
        return self.render_to_response(self.get_context_data(form=form, formset=formset))

    def post(self, request, *args, **kwargs):
        if getattr(self, 'is_update_view', False):
            self.object = self.get_object()
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        formset_class = self.get_formset_class()
        formset = self.get_formset(formset_class)
        if form.is_valid() and formset.is_valid():
            return self.form_valid(form, formset)
        else:
            return self.form_invalid(form, formset)

    def form_valid(self, form, formset):
        self.object = form.save()
        formset.instance = self.object
        formset.save()
        return redirect(self.object.get_absolute_url())

    def get_formset_class(self):
        return self.formset_class

    def get_formset(self, formset_class):
        return formset_class(**self.get_formset_kwargs())

    def get_formset_kwargs(self):
        kwargs = {
            'instance': self.object
        }
        if self.request.method in ('POST', 'PUT'):
            kwargs.update({
                'data': self.request.POST,
                'files': self.request.FILES,
            })

        return kwargs

    def form_invalid(self, form, formset):
        return self.render_to_response(self.get_context_data(form=form, formset=formset))

对不起,我无法在编辑器中修复我的mixin,但是mixin中的函数在类中。

sorry i cant fix in editor my mixin, but functions in mixin is in class.

所以当我需要使用conditon做额外的= 0时有1个以上的联系人要购物。但是当我按下按钮时,会添加更多联系方式。
这是创建页面-创建视图

So where i need to use conditon to do extra=0, when i have more than 1 contact to shop. but when i will press button add more it will be add one more form of contact. this is create page - create view

这是我的更新页面-更新视图

因此,当我更新商店设置时,我不想显示第二个模板集(如果它为空),只是当我单击底部的第一个按钮时。

so when i update shop settings i don't want to show second formset if it empty, just when i will click to first button at the bottom.

推荐答案

答案很简单,我应该在

 ShopInlineFormSet = inlineformset_factory(Shop, Contacts, extra=1,max_num=1,
                                  fields=(
                                      'published', 'phone', 'address', 'place', 'latitude',
                                      'longitude', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday',
                                      'saturday', 'sunday'), can_delete=True)

这篇关于内联表单集工厂更新视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆