inline formset factory update view

删除回忆录丶 提交于 2019-12-24 06:03:07

问题


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

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))

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

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

this is my update page - update 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.


回答1:


The answer is was simple, i should use max_num=1 in

 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)


来源:https://stackoverflow.com/questions/45278491/inline-formset-factory-update-view

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!