python-3.x - 单一 View 中的多模型表单集工厂

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

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

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:- 当我仅使用一种模型表单集时,它工作得很好。

PS2:- 没有显示错误。

最佳答案

您需要使用前缀自定义多个表单集。前缀为每个表单设置自定义 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

关于python-3.x - 单一 View 中的多模型表单集工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49612087/

相关文章:

python - Python 中复杂列表理解语句的操作顺序和内部创建资源的数量

javascript - API 是否永久存储从网站提取的数据?

mysql - SQL - 选择需要填充的变量

django - 在 Django 中,如何从模型/子项预填充编辑表单,但将提交保存为新实例?

django - 通过Django代码将值分配给一对多字段

python - 在使用从列表中计算出最接近数字的代码时遇到问题

python-3.x - 使用整数的内存 View 索引 Cython 内存 View

python - 无法在本地安装 Google Colab

php - MySQL删除记录

python - 如何从 Django 管理面板中删除多余的 "s"?