【问题标题】:Django inlineformset_factory in UpdateView formset data is not updateUpdateView formset 数据中的 Django inlineformset_factory 未更新
【发布时间】:2020-05-08 08:33:20
【问题描述】:

我在我的项目中使用基于类的视图。在使用多个表单(inlineformset_factory)的 CreateView 中,我成功保存了两个表单数据。

但是当我尝试使用基于类的视图 (UpdateView) 编辑我的表单集时,只有第一个表单数据被成功更新。

但是表单集(inlineformset_factory)数据没有更新。 请帮助找出我的(UpdateView)中的问题。

views.py

class MaterialRequest_update(UpdateView):
    template_name = 'inventory/edit_files/material_request.html'
    form_class = MaterialRequestForm
    model = MaterialRequest
    success_url = reverse_lazy('inventory-material-request')

    def get_queryset(self):
        id = self.kwargs['pk']
        return MaterialRequest.objects.filter(pk=id)

    def get_context_data(self, **kwargs):
        context = super(MaterialRequest_update, self).get_context_data(**kwargs)
        if self.request.POST:
            context['form'] = MaterialRequestForm(self.request.POST, instance=self.object)
            context['formset'] = MaterialRequestFormset(
                self.request.POST, instance=self.object)
        else:
            context['form'] = MaterialRequestForm(instance=self.object)
            context['formset'] = MaterialRequestFormset(instance=self.object)

        return context


    def form_valid(self, form):
        context = self.get_context_data()
        formset = context['formset']

        if form.is_valid() and formset.is_valid():
            form.save()
            formset.save()

        return super().form_valid(form)

forms.py

# Main Form

    class MaterialRequestForm(forms.ModelForm):
        class Meta:
            model = MaterialRequest
            fields = [
                'location', 'job', 'task_num', 'supervisor', 'entry_serialno', 'date', 
                'department', 'ref', 'other_info', 'attachment'
            ]
            labels = {
                'location':'Location', 'job':'Job', 'task_num':'Estimate No', 
                'supervisor':'Supervisor', 'entry_serialno':'Entery No', 'date':'Date', 
                'department':'Department', 'ref':'Reference', 'other_info':'Other Info', 
                'attachment':'Attachment File'
            }
            widgets = {
                'location': forms.Select(attrs={'class':'form-control select-search'}), 
                'job': forms.Select(attrs={'class':'form-control select-search'}), 
                'task_num': forms.TextInput(attrs={'class':'form-control'}), 
                'supervisor': forms.TextInput(attrs={'class':'form-control'}), 
                'entry_serialno': forms.TextInput(attrs={'class':'form-control'}), 
                'date': forms.DateInput(attrs={'class':'form-control pickadate'}), 
                'department': forms.Select(attrs={'class':'form-control select-search'}), 
                'ref': forms.TextInput(attrs={'class':'form-control'}), 
                'other_info': forms.Textarea(attrs={'class':'form-control', 'rows':3}),
                'attachment': forms.ClearableFileInput(attrs={'class':'form-control'})
            }

            def clean(self):
                fields = self.cleaned_data


    # Formset start from here

    MaterialRequestFormset = inlineformset_factory(
        MaterialRequest, 
        MaterialRequestProducts,
        form = MaterialRequestForm,
        extra=1,
        can_delete=True,
        max_num=200,
        validate_max=200,
        fields=('product', 'quantity', 'unit', 'stock'),
        widgets={
            'product': forms.Select(attrs={'class':'form-control select-search'}), 
            'quantity': forms.NumberInput(attrs={'class':'form-control'}), 
            'unit': forms.Select(attrs={'class':'form-control select-search'}), 
            'stock': forms.NumberInput(attrs={'class':'form-control'}),
        }
    )

models.py

class MaterialRequest(models.Model):
        location = models.ForeignKey(to='administrator.Location', related_name='materialreq_location', on_delete=models.CASCADE)
        job = models.ForeignKey(to='master.Job', related_name='materialreq_job', on_delete=models.CASCADE)
        task_num = models.CharField(max_length=100, blank=True) 
        supervisor = models.CharField(max_length=100, blank=True) 
        entry_serialno = models.CharField(max_length=100, blank=True) 
        date = models.CharField(max_length=100, blank=True)
        department = models.ForeignKey('master.Department', related_name='department', on_delete=models.CASCADE, null=True)
        ref = models.CharField(max_length=100, blank=True)
        other_info = models.TextField(blank=True)
        attachment = models.FileField(upload_to='files/inventory/material_request/%Y/%m/%d/', null=True, blank=True)
        added_by = models.CharField(max_length=200, default='Azhar Saleem')
        created_at = models.DateTimeField(auto_now_add=True)
        updated_at = models.DateTimeField(auto_now=True)

         objects = models.Manager

         def __str__(self):
              return self.job

          class Meta:
              db_table = 'inventory_material_request'
              verbose_name = 'Material_Request'
              verbose_name_plural = 'Material_Requests'



    #Formset model start from here...

class MaterialRequestProducts(models.Model):
        material_request = models.ForeignKey(MaterialRequest, related_name='materialrequest', on_delete=models.CASCADE)
        product = models.ForeignKey(Products, related_name='products', on_delete=models.CASCADE)
        quantity = models.BigIntegerField()
        unit = models.ForeignKey('master.UnitOfMeasurements', related_name='unit', on_delete=models.CASCADE)
        stock = models.DecimalField(max_digits=999, decimal_places=2)
        add_by = models.CharField(max_length=100, default='Azhar Saleem')
        created_at = models.DateTimeField(auto_now_add=True)
        updated_at = models.DateTimeField(auto_now=True)

        objects = models.Manager

        def __str__(self):
           return self.product

        class Meta:
           db_table = 'inventory_material_request_products'
           verbose_name = 'Material_Request_Product'
           verbose_name_plural = 'Material_Request_Products'

【问题讨论】:

    标签: python django django-forms inline-formset


    【解决方案1】:

    试试这个。

    class MaterialRequest_update(UpdateView):
        model = MaterialRequest
        form_class = MaterialRequestForm
        template_name = 'inventory/edit_files/material_request.html'
        slug_field = 'uid'
        slug_url_kwarg = 'uuid'
        success_message = 'Data saved successfully'
    
        def get_success_url(self):
            return reverse_lazy('inventory-material-request')
    
        def get_context_data(self, **kwargs):
            context = super(MaterialRequest_update, self).get_context_data(**kwargs)
            if self.request.POST:
                context['form'] = MaterialRequestForm(self.request.POST, instance=self.object)
                context['formset'] = MaterialRequestFormset(self.request.POST,
                                                            instance=self.object)
            else:
                context['form'] = MaterialRequestForm(instance=self.object)
                context['formset'] = MaterialRequestFormset(instance=self.object)
            return context
    
        def post(self, request, *args, **kwargs):
            self.object = self.get_object()
            form_class = self.get_form_class()
            form = self.get_form(form_class)
            formset = MaterialRequestFormset(self.request.POST, instance=self.object)
            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 HttpResponseRedirect(self.get_success_url())
    
        def form_invalid(self, form, formset):
            return self.render_to_response(self.get_context_data(form=form, formset=formset))
    

    【讨论】:

    • Sachin Singh,当我点击提交按钮时,表单没有提交。只是页面刷新,数据不保存。
    • 在您的 form_valid 和 form_invalid 函数中打印一些内容,以了解验证是否通过。
    • Print show me in Terminal "form is not valid" def post(self, request, *args, **kwargs): self.object = self.get_object() form_class= self.get_form_class() form = self.get_form(form_class) formset = MaterialRequestFormset(self.request.POST, instance=self.object) if (form.is_valid() and formset.is_valid()): print('form有效') return self.form_valid(form, formset) else: print('form is not valid') return self.form_invalid(form, formset)
    猜你喜欢
    • 2020-04-24
    • 2014-10-14
    • 2017-09-21
    • 2023-03-17
    • 2011-01-04
    • 2013-08-22
    • 2023-03-08
    • 1970-01-01
    • 2013-12-19
    相关资源
    最近更新 更多