【问题标题】:What is the correct way to auto-create related model objects in django-registration?在 django-registration 中自动创建相关模型对象的正确方法是什么?
【发布时间】:2017-10-08 17:58:42
【问题描述】:

我是一个 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块的作用是什么?

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

【问题讨论】:

    标签: python django django-registration


    【解决方案1】:
    • cleaned_data 是该表单中每个字段的所有验证后的数据字典。现在你可以决定是否依赖它(最好你应该)。所以作为一个伪代码,我们可以说cleaned_data + errors 将是所有字段。
    • commit 用于决定它是否应该提交到 db(write)。从上面的代码中,要添加一个相关的模型对象,如profile,必须首先创建原始对象(User)。这就是它强制提交的原因。
    • 要在对象创建时添加相关对象,有多种方法,如post_save 信号、覆盖模型save、覆盖表单save 等。所以你使用的是一种好方法,我想说。李>

    【讨论】:

    • 感谢您抽出宝贵时间再次向我保证。如果可以的话,对commit 进行一点跟进:我仍然不清楚为什么如果我在我的两个saves 之前加上if commit:,那么它就不起作用了。定义中的提交自动设置为True 吗?看到这个this link,其中用户创建commit首先设置为False,然后在save()之前有一个if commit
    • 另外,如果我可以再提出一个问题:原始代码返回一个 user, userprofile 的元组,如果我尝试返回 user, business,则会出现错误。这个回报在哪里使用?为什么它会给我一个错误?
    • 这些答案您需要检查。但请检查super。你打电话给super(UserCreationForm)。是super(GeneralUserForm) 吗?在你的第一个形式
    猜你喜欢
    • 1970-01-01
    • 2015-10-15
    • 2015-05-22
    • 1970-01-01
    • 2021-01-25
    • 1970-01-01
    • 1970-01-01
    • 2015-02-11
    • 1970-01-01
    相关资源
    最近更新 更多