Python 用于多对多关系的内联表单集的挂件

Python 用于多对多关系的内联表单集的挂件,python,django,Python,Django,按照中的Kevin Dias说明,我尝试为两个相关模型生成一个表单。这似乎适用于一对多关系,但是我在使用多对多关系时遇到了问题 以下是用户角色管理的一些示例代码: #models.py from django.db import models class Role(models.Model): # for each role there can be multiple users role_name=models.CharField(max_length=20) class User

按照中的Kevin Dias说明,我尝试为两个相关模型生成一个表单。这似乎适用于一对多关系,但是我在使用多对多关系时遇到了问题

以下是用户角色管理的一些示例代码:

#models.py
from django.db import models

class Role(models.Model): # for each role there can be multiple users
    role_name=models.CharField(max_length=20)

class User(models.Model): # each user can have multiple roles
    name=models.CharField(max_length=20)
    role=models.ManyToManyField(Role, through='UserRole')

class UserRole(models.Model): # table to store which user has which roles
    role=models.ForeignKey(Role)
    user=models.ForeignKey(User)

# forms.py
from django.forms import ModelForm
from django.forms.models import inlineformset_factory

from rightmanagement.models import Role, User

class UserForm(ModelForm):
    class Meta:
        model = User

RoleFormSet = inlineformset_factory(User, Role) # this is probably the line that causes the problem

# views.py
from django.http import HttpResponseRedirect
from rightmanagement.models import User
from rightmanagement.forms import RoleFormSet, UserForm

# Create view
from django.views.generic import CreateView
class UserCreate(CreateView):
    model = User
    form_class = UserForm

    def get(self, request, *args, **kwargs):
        """
        Handles GET requests and instantiates blank versions of the form
        and its inline formsets.
        """
        self.object = None
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        role_form = RoleFormSet()
        return self.render_to_response(
            self.get_context_data(form=form,
                                  role_form=role_form))

    def post(self, request, *args, **kwargs):
        """
        Handles POST requests, instantiating a form instance and its inline
        formsets with the passed POST variables and then checking them for
        validity.
        """
        self.object = None
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        role_form = RoleFormSet(self.request.POST)
        if (form.is_valid() and role_form.is_valid()):
            return self.form_valid(form, role_form)
        else:
            return self.form_invalid(form, role_form)

    def form_valid(self, form, role_form):
        """
        Called if all forms are valid. Creates a Recipe instance along with
        associated Ingredients and Instructions and then redirects to a
        success page.
        """
        self.object = form.save()
        role_form.instance = self.object
        role_form.save()
        return HttpResponseRedirect(self.get_success_url())

    def form_invalid(self, form, role_form):
        """
        Called if a form is invalid. Re-renders the context data with the
        data-filled forms and errors.
        """
        return self.render_to_response(
            self.get_context_data(form=form,
                                  role_form=role_form))
这些设置导致错误消息
没有外键

做一些研究,我发现了这个:。似乎内联表单集仅适用于
ForeignKey
,而不适用于
ManyToManyField
。也可以这样解释


然而,我认为在这种特殊情况下,外键而不是多对多关系没有任何意义。对于多对多关系,Django内置的内联表单集的挂件会是什么样子?其目的是构建一个表单,允许将用户分配给已经存在的角色,或者创建新角色,并在尚未存在的情况下将其分配给用户。

正如您可能知道的,您无法编辑具有内联表单集的多对多关系。但是,您可以编辑贯穿模型。因此,对于内联表单集,只需将模型设置为直通模型,如下所示:

RoleFormSet = inlineformset_factory(UserRole, User.role.through)

非常感谢。这样做,我再也不会收到错误消息了。但是,我可以在表单中添加新角色吗?毕竟,模型
Role
既不会包含在
forms.py
中,也不会包含在
views.py
User.Role.though