Python 多个链接的Django表单,一次提交

Python 多个链接的Django表单,一次提交,python,django,python-2.7,Python,Django,Python 2.7,我有应用和角色的模型。Role链接到一个FK Role_类型,该类型由FK链接到可以使用这些Role_类型的应用程序(对于这个问题来说,这有点过于简单,但我认为它已经足够了)。我需要一种方法来创建一个表单来创建一个新的应用程序,并创建将相关角色分配给人员的记录(尽管可以将其保留为空) 我已经为应用程序创建了表单,并在页面上显示了相关的角色类型,下拉列表中填充了用户。但是,点击submit并没有创建任何关联的角色记录。我所有的研究似乎都回到了内联模型表单上,但文档对我来说并没有真正意义——示例中的

我有应用和角色的模型。Role链接到一个FK Role_类型,该类型由FK链接到可以使用这些Role_类型的应用程序(对于这个问题来说,这有点过于简单,但我认为它已经足够了)。我需要一种方法来创建一个表单来创建一个新的应用程序,并创建将相关角色分配给人员的记录(尽管可以将其保留为空)

我已经为应用程序创建了表单,并在页面上显示了相关的角色类型,下拉列表中填充了用户。但是,点击submit并没有创建任何关联的角色记录。我所有的研究似乎都回到了内联模型表单上,但文档对我来说并没有真正意义——示例中的输入似乎与我需要的内容没有关联

我知道这看起来像是重复的,但请相信我,我已经看过了所有与此相关的SO问题

编辑:我的帖子如下:
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做什么?