Django:同时保存多个模型(复杂的情况)

时间:2011-02-17 18:41:16

标签: django django-queryset modelform

嗯,这实际上可能是一个简单的案例,但我很难搞清楚。

我有两个用户注册渠道(公司和其他人)。当企业用户通过我的注册表单创建用户实例时,我还希望他们输入创建相关实例的辅助表单(基于Website和Organization_Contact模型)。

我知道如何通过发出额外的同步或异步请求来解决这个问题,但我希望用户填写三个表单并单击提交。

我的问题是,其他两种形式依赖于用户外键作为字段。我已经将该字段设置为“null = True,blank = True”,以便我可以在没有外键的情况下验证和保存表单,但我最终希望将该键添加到两个模型实例中。

我认为我可以验证这三种形式,保存UserForm,然后使用模型查询集返回新的User.id(所有在一个视图中)。然后我将user_id值添加到另外两个表单词典(WebsiteForm和Organization_ContactForm)。

它可以这样工作:

def register_company(request):
    if request.method=='POST'
       uform=UserCreationForm(request.POST, prefix='user')
       sform=SiteForm(request.POST, prefix='site')
       oform=OrgForm(request.POST, prefix='site')
       if uform.is_valid() and sform.is_valid() and oform.is_valid():
            uform.save()
            user=User.objects.get(email__iexact=uform.cleaned_data['email'])
            uid=unicode(user.id)
       #now I'd add uid back into the SiteForm and Orgform dictionaries and then save both instances              

问题: 1)不确定我是否可以保存模型,然后在单个视图中将该模型实例作为查询集返回

2)我说我不确定,因为我无法通过尝试将变量传递给查询集的问题。

get manager方法似乎不接受那里的变量。我假设同样多,因为我传递了一个等效的硬编码字符串并且它有效。

好的,所以我正在考虑创建一个新的管理器方法(电子邮件),它接受一个变量参数(已清理的电子邮件字段),然后重试保存一个模型,检索模型ID数据和保存其他模型的过程。

我还以为我可以通过帖子保存信号处理这个问题。

这里的大方向非常有帮助。我需要一个起点。

2 个答案:

答案 0 :(得分:2)

这些都是ModelForm s?

if request.method=='POST'
   uform=UserCreationForm(request.POST, prefix='user')
   sform=SiteForm(request.POST, prefix='site')
   oform=OrgForm(request.POST, prefix='site')
   if uform.is_valid() and sform.is_valid() and oform.is_valid():
        # save returns the object 
        user = uform.save()

        # commit = false doesn't save to DB.
        site = sform.save(commit=False)
        site.user = user
        site.save()

        org = oform.save(commit=False)
        org.user = user
        org.save()

关于评论的更新:为什么在一个地方可以将这种形式保存逻辑扩展到多个区域和文件(信号,表格保存)?

代码更具可读性,甚至可以保存代码行。除非它将在全球范围内使用。

答案 1 :(得分:0)

我就是这样做的:

def register_company(request):
    uform=UserCreationForm(request.POST or None, prefix='user')
    sform=SiteForm(request.POST or None, prefix='site')
    oform=OrgForm(request.POST or None, prefix='site')

    if request.POST and all((uform.is_valid(), sform.is_valid(), oform.is_valid()):
        user = uform.save()
        sform.save(user)
        oform.save(user)

    ruturn ...

class UserCreateionForm(ModelForm):
    Meta:
        model = User

class SiteForm(ModelForm):
    Meta:
        model=Site
        exclude=['user', ]

    def save(self, user, commit=True):
        self.instance.user = user
        return super(SiteForm, self).save(commit=commit)