遵循Kevin Dias在this article中的说明,我尝试为两个相关模型生成一个表单.这似乎适用于一对多的关系,但是我遇到了使用多对多关系的问题.
#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,**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,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))
这些设置会导致错误消息< class'rightmanagement.models.Role'>没有ForeignKey到< class'rightmanagement.models.User'>.
做了一些研究我发现了这个:Django inlineformset_factory and ManyToMany fields.看起来内联表单集只适用于ForeignKey而不适用于ManyToManyField. the docs也可以这样解释.
但是,我认为在特定情况下,外键而不是多对多关系是没有任何意义的. Django的内置内联formset的挂件如何看起来像是多对多的关系?目标是构建一个表单,允许将用户分配给已存在的角色或创建新角色,如果用户尚不存在则将其分配给用户.
最佳答案
您可能已经意识到,您无法使用内联表单集编辑多对多关系.但是,您可以编辑直通模型.因此,对于内联formset,您只需将模型设置为直通模型,如下所示:
RoleFormSet = inlineformset_factory(UserRole,User.role.through)