【问题标题】:Multiple model formset factory in single view单一视图中的多个模型表单集工厂
【发布时间】:2018-09-11 17:14:12
【问题描述】:

我在一个视图中有多个模型表单集。这用于编辑配置文件的现有数据并由用户添加新数据。当用户尝试编辑和保存数据时,数据没有保存在数据库中。我做错了什么?

views.py

def profile_edit(request,username):
    profile_edit = get_object_or_404(User,username=username)
    userprofile  = get_object_or_404(UserProfile,user__username=username)
    UserDegreeFormset = modelformset_factory(Degree,form = EditForm2,extra=1,validate_max=True,can_delete=True)
    degree = Degree.objects.filter(user__username=username)
    UserCertificateFormset = modelformset_factory(Certificate,form=EditForm4,extra=1,validate_max=True,can_delete=True)
    certificate = Certificate.objects.filter(user__username=username)
    UserSocialFormset = modelformset_factory(SocialMedia,form=EditForm5,extra=1,validate_max=True,can_delete=True)
    sociallink = SocialMedia.objects.filter(user__username=username)
    if request.user == profile_edit and request.user.is_authenticated:
        if request.method == "POST":
            form = EditForm(request.POST or None,instance=profile_edit)
            form1 = EditForm1(request.POST or None,instance=userprofile)
            form2 = UserDegreeFormset(request.POST or None,queryset= degree)
            form4 = UserCertificateFormset(request.POST or None,queryset=certificate)
            form5 = UserSocialFormset(request.POST or None, queryset=sociallink)
            if form.is_valid() and form1.is_valid() and form2.is_valid() and form4.is_valid() and form5.is_valid():
                form.save()
                form1.save()
                degs = form2.save(commit=False)
                for obj in form2.deleted_objects:
                    obj.delete()
                for deg in degs:
                    deg.user = profile_edit
                    deg.save()
                certs = form4.save(commit=False)
                for obj in form4.deleted_objects:
                    obj.delete()
                for cert in certs:
                    cert.user = profile_edit
                    cert.save()
                links = form5.save(commit=False)
                for obj in form5.deleted_objects:
                    obj.delete()
                for link in links:
                    link.user = profile_edit
                    link.save()
                return redirect('profile_edit',username=username)

        else:
            form = EditForm(instance=profile_edit)
            form1 = EditForm1(instance=userprofile)
            form2 = UserDegreeFormset(queryset=degree)
            form4 = UserCertificateFormset(queryset=certificate)
            form5 = UserSocialFormset(queryset=sociallink)
        context = {
            'form':form,
            'form1':form1,
            'form2':form2,
            'form4':form4,
            'form5':form5,
        }
        return render(request,'userprofile/profile_edit.html', context)
    else:
        raise PermissionDenied

forms.py

class EditForm(forms.ModelForm):
    email = forms.EmailField(label='Email Address',disabled=True)
    class Meta:
        model = User
        fields = ('username','email','first_name','last_name',)


class EditForm1(forms.ModelForm):
    date_of_birth = forms.DateField(widget=forms.SelectDateWidget)
    class Meta:
        model = UserProfile
        fields = ('date_of_birth','phone_no','overall_rating','preferred_language',)

class EditForm2(forms.ModelForm):
    class Meta:
        model = Degree
        exclude = ("user",)


class EditForm4(forms.ModelForm):
    class Meta:
        model = Certificate
        fields = ('title','institution_name',)

class EditForm5(forms.ModelForm):
    class Meta:
        model = SocialMedia
        fields = ('website_name','website_link',)

PS1:- 当我只使用一个模型 formset 时,它工作得很好。

PS2:- 没有显示错误。

【问题讨论】:

    标签: python-3.x web django-models django-forms formset


    【解决方案1】:

    您需要使用前缀自定义多个表单集。前缀为每个表单设置自定义 id。
    views.py

    def profile_edit(request,username):
        profile_edit = get_object_or_404(User,username=username)
        userprofile  = get_object_or_404(UserProfile,user__username=username)
        UserDegreeFormset = modelformset_factory(Degree,form = EditForm2,extra=1,validate_max=True,can_delete=True)
        degree = Degree.objects.filter(user__username=username)
        UserCertificateFormset = modelformset_factory(Certificate,form=EditForm4,extra=1,validate_max=True,can_delete=True)
        certificate = Certificate.objects.filter(user__username=username)
        UserSocialFormset = modelformset_factory(SocialMedia,form=EditForm5,extra=0,validate_max=True)
        sociallink = SocialMedia.objects.filter(user__username=username)
        if request.user == profile_edit and request.user.is_authenticated:
            if request.method == "POST":
                form = EditForm(request.POST or None,instance=profile_edit)
                form1 = EditForm1(request.POST or None,instance=userprofile)
                form2 = UserDegreeFormset(request.POST or None,prefix=str(1),queryset= degree)
                form4 = UserCertificateFormset(request.POST or None,prefix=str(2),queryset=certificate)
                form5 = UserSocialFormset(request.POST or None,prefix=str(3),queryset=sociallink)
                if form.is_valid() and form1.is_valid() and form2.is_valid() and form4.is_valid() and form5.is_valid():
                    form.save()
                    form1.save()
                    degs = form2.save(commit=False)
                    for obj in form2.deleted_objects:
                        obj.delete()
                    for deg in degs:
                        deg.user = profile_edit
                        deg.save()
                    certs = form4.save(commit=False)
                    for obj in form4.deleted_objects:
                        obj.delete()
                    for cert in certs:
                        cert.user = profile_edit
                        cert.save()
                    links = form5.save(commit=False)
                    for link in links:
                        link.user = profile_edit
                        link.save()
                    return redirect('profile_edit',username=username)
    
            else:
                form = EditForm(instance=profile_edit)
                form1 = EditForm1(instance=userprofile)
                form2 = UserDegreeFormset(prefix=str(1),queryset=degree)
                form4 = UserCertificateFormset(prefix=str(2),queryset=certificate) 
                form5 = UserSocialFormset(prefix=str(3),queryset=sociallink)
            context = {
                'form':form,
                'form1':form1,
                'form2':form2,
                'form4':form4,
                'form5':form5,
            }
            return render(request,'userprofile/profile_edit.html', context)
        else:
            raise PermissionDenied
    

    阅读更多关于 django 官方文档的信息:-
    multiple-formsets-in-view

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-29
      • 1970-01-01
      • 1970-01-01
      • 2014-01-01
      • 2019-03-31
      • 1970-01-01
      • 2011-02-20
      • 1970-01-01
      相关资源
      最近更新 更多