在django-registration中自动创建相关模型对象的正确方法是什么?

时间:2017-05-10 07:51:15

标签: python django django-registration

如果我没有使用正确的术语,我是Django的新手,并提前道歉。

我正在使用django-registration在我的网络应用上注册用户。我已成功使用我的自定义用户模型GeneralUser进行了调整。

从概念上讲,每个GeneralUser都有Business,这是我定义的另一个模型。无论这是否正确,我决定在没有相关Business对象的情况下注册用户。

我已经阅读了无数关于自定义django表单的线程,最后经过几天不成功的尝试后,an answer得到了帮助解决方案。但是,我不确定我的代码是否正确/安全。这是我的改编,接着是链接答案:

我的改编

class GeneralUserForm(UserCreationForm):
    business_name = forms.CharField(required=True)

    class Meta:
        model = GeneralUser
        fields = ['username', 'email', 'password1',
                  'password2', 'business_name']

    def save(self, commit=True):
        user = super(UserCreationForm, self).save(commit=True)
        business = Business(name=user.business_name, owner=user)

        # notice: no if-block
        user.save()
        business.save()
        # notice: returning only a user-instance
        return user

此代码成功创建用户和业务对象,并创建关系。看一下原始的答案代码,我想知道是否有一些我不想要的关键:

回答我的代码基于:

class UserCreateForm(UserCreationForm):
    job_title = forms.CharField(max_length=100, required=True)
    age = forms.IntegerField(required=True)

    class Meta:
        model = User

    def save(self, commit=True):
        if not commit:
            raise NotImplementedError("Can't create User and UserProfile without database save")
        user = super(UserCreateForm, self).save(commit=True)
        user_profile = UserProfile(user=user, job_title=self.cleaned_data['job_title'], 
            age=self.cleaned_data['age'])
        user_profile.save()
        # notice: multiple returns
        return user, user_profile

关于差异的一些问题:

  • 如果我这样结束,我的代码为什么不起作用:

if commit:
        user.save()
        business.save()
        return user
  • 我没有使用cleaned_data,可以吗?

  • 原始代码中if not commit块的用途是什么?

  • 最重要的是,这是一种处理用户注册的“合法方式”,需要在创建时自动建立对象关系吗?

1 个答案:

答案 0 :(得分:1)

  • cleaned_data是该表单中每个字段中所有验证后的数据字典。现在你可以决定是否依赖它(最好你应该)。因此,我们可以说cleaned_data + errors将是所有字段。
  • commit用于决定是否应该提交db(write)。从上面的代码中,要添加像profile这样的相关模型对象,必须首先创建原始对象(User)。这就是为什么它会强制提交。
  • 要在对象创建时添加相关对象,有多种方法,如post_save信号,覆盖模型save,覆盖形式save等等。因此,您使用的方法很好,我会说。