首页 > 解决方案 > 如何在单个 django 视图中组合两个 ModelForm

问题描述

大家好,所以我有两个模型,其中一个有一个指向另一个的外键字段,我有每个模型类的模型表单,在我的views.py中,我想用另一个外键点制作模型模型

我在 forms.py 中创建了一个模型表单(CharacterForm 和 RoleForm),它会显示所有字段,但在我的 html 中,我会隐藏玩家字段(指向另一个模型的外键)所以在我的 views.py 中我会自动制作新创建的角色玩家。

模型.py

class Character(models.Model):
    #some fields

class Role(models.Model):
    player = models.ForeignKey(Character, on_delete=models.PROTECT, 
        related_name='the_player')

视图.py

    def NewRole(request):
        if request.method == 'POST'
            form = CharacterForm()
            formset = RoleForm()
            if all([form.is_valid, formset.is_valid]):
                role_player = form.save()
                formset.player = role_player
                formset.save()
                return redirect('index')
        else:
            form = CharacterForm()
            formset = RoleForm()
            return render(request, 'new_role.html', {'form':form, 
                'formset':formset})

我只是希望角色模型下的玩家字段指向用户刚刚创建的角色模型,我不知道最好的方法。我认为这会起作用,但我不断收到 ForeignKey Constraint 错误。

标签: djangodjango-modelsdjango-formsdjango-views

解决方案


您收到该错误,因为您没有的值设置为该对象player实例,因此当您创建对象时该player字段仍然存在。None

您可以将其从您的 中排除RoleForm,例如:

# app/forms.py

from django import forms
from app.models import Character, Role

class CharacterForm(forms.ModelForm):

    class Meta:
        model = Character

class RoleForm(forms.ModelForm):

    class Meta:
        model = Role
        exclude = ('player', )

接下来,在您的视图中,您构建了两个表单,并且Character一旦将其保存到Role您正在构建的对象的实例,您就可以将其链接,例如:

from app.forms import CharacterForm, RoleForm

def new_role(request):
    if request.method == 'POST'
        cform = CharacterForm(request.POST)
        rform = RoleForm(request.POST)
        if cform.is_valid() and rform.is_valid():
            character = cform.save()
            rform.instance.player = character
            rform.save()
            return redirect('index')
    else:
        rform = CharacterForm()
        cform = RoleForm()
    return render(request, 'new_role.html', {'rform': form, 'cform': cform})

在您的模板中,您可以简单地将其呈现为:

<form method="post" action="{% url 'name-of-new-role-view' %}">
    {% csrf_token %}
    {{ rform }}
    {{ cform }}
    <input type="submit">
</form>

推荐阅读