Python 多个链接的Django表单,一次提交
我有应用和角色的模型。Role链接到一个FK Role_类型,该类型由FK链接到可以使用这些Role_类型的应用程序(对于这个问题来说,这有点过于简单,但我认为它已经足够了)。我需要一种方法来创建一个表单来创建一个新的应用程序,并创建将相关角色分配给人员的记录(尽管可以将其保留为空) 我已经为应用程序创建了表单,并在页面上显示了相关的角色类型,下拉列表中填充了用户。但是,点击submit并没有创建任何关联的角色记录。我所有的研究似乎都回到了内联模型表单上,但文档对我来说并没有真正意义——示例中的输入似乎与我需要的内容没有关联 我知道这看起来像是重复的,但请相信我,我已经看过了所有与此相关的SO问题 编辑:我的帖子如下:Python 多个链接的Django表单,一次提交,python,django,python-2.7,Python,Django,Python 2.7,我有应用和角色的模型。Role链接到一个FK Role_类型,该类型由FK链接到可以使用这些Role_类型的应用程序(对于这个问题来说,这有点过于简单,但我认为它已经足够了)。我需要一种方法来创建一个表单来创建一个新的应用程序,并创建将相关角色分配给人员的记录(尽管可以将其保留为空) 我已经为应用程序创建了表单,并在页面上显示了相关的角色类型,下拉列表中填充了用户。但是,点击submit并没有创建任何关联的角色记录。我所有的研究似乎都回到了内联模型表单上,但文档对我来说并没有真正意义——示例中的
QueryDict:{u'roles-MAX_NUM_FORMS':[u'1000',u'roles-1-role_type':[u'4'],u'roles-0-user':[u'1'],u'app-owner':[u'1'],u'app-name':[u'1234'],u'app-serviceTier':[u'],u'app-jiraProject':[u'],u'roles-TOTAL_-FORMS':[u'2'],u'1-roles'],u'3'],u'csrfmiddlewaretoken':[u'eGsDwtsSQJfl0'],u'roles-INITIAL_FORMS':[u'2']}>
。打印RolesFormSet给了我完全相同的输出(见下面的注释)
models.py
class Item(models.model):
name = models.CharField(max_length=255)
roles = models.ManyToManyField(User, through='Role')
class Application(Item):
other_assorted_attributes = foo
class RoleType(models.Model):
name = models.CharField(max_length=255)
class ItemTypeRoleMapping(models.Model):
''' pairs role-types (e.g., Developer) with an Item class they are relevant to'''
roleType = models.ForeignKey(RoleType)
itemType = models.CharField(max_length=255, choices=itemChoices)
class Role(models.Model):
role_type = models.ForeignKey(RoleType)
user = models.ForeignKey(User)
item = models.ForeignKey(Item)
views.py
def buildRolesFormset(itemClass):
''' given an item, build a form for all associated roles '''
roleTypesForItem = ItemTypeRoleMapping.objects.all().filter(itemType=itemClass.__name__)
applicable_roles = [{'role_type': roleType} for roleType in roleTypesForItem]
# formset = rolesFormSet(initial=initial, prefix='roles')
RoleFormSet = inlineformset_factory(Application, Role, extra=len(roleTypesForItem), can_delete=False)
formset = RoleFormSet()
for subform, data in zip(formset.forms, applicable_roles):
subform.initial = data
return formset
def new(request):
''' Create a new application '''
user = request.user
# check permission
if request.method == 'POST':
appform = AppForm(request.POST, prefix='app')
if appform.is_valid():
app = appform.save(commit=False)
rolesInlineFormSet = inlineformset_factory(Application, Role)
# pdb.set_trace()
rolesFormSet = rolesInlineFormSet(request.POST, instance=app, prefix='roles')
if rolesFormSet.is_valid():
rolesFormSet.save()
else:
print rolesFormSet.errors
app = appform.save()
# check rolesFormSet
return redirect(reverse('index'))
else:
appform = AppForm(prefix='app')
rolesFormSet = buildRolesFormset(Application)
return render(request, 'who/editapp.html',
{'appform': appform,
'rolesFormSet': rolesFormSet
})
在没有更多信息的情况下很难判断,但看起来您没有在视图中保存角色表单集。您需要在调用
form.save()
的同时调用rolesFormset.save()。另外,我想您想将角色附加到创建的应用程序?在您看来,这样的方法应该有效:
if request.method == 'POST':
form = AppForm(request.POST)
rolesFormset = RoleForm(request.POST)
if form.is_valid() and rolesFormset.is_valid():
app = form.save()
roles = rolesFormset.save()
for role in roles:
app.roles.add(role)
return redirect(reverse('index'))
更新:假定models.py已过时,并且角色实际上对用户有一个外来密钥,问题是您在此处设置前缀:
rolesFormSet = rolesInlineFormSet(request.POST, instance=app, prefix='roles')
但不在buildRolesFormset
函数中。在该功能中,请执行以下操作:
formset = RoleFormSet(prefix='roles')
我的角色表单集没有清除有效的,我不知道为什么。似乎没有填充任何字段,但当我在pdb中翻出rolesFormSet.data时,我得到了
,我不确定为什么它没有保存,而且还弄不清楚为什么有“应用程序”前缀信息。FWIW,打印POST请求会给我完全相同的输出。您应该能够通过执行打印角色表单集来了解表单集无效的原因。视图中出现错误。我这样做了--它告诉我所有字段均为空且为必填字段。这就是buildRolesFormset
do做什么?