Django - 用户和用户配置文件表单创建两个配置文件而不是一个

时间:2017-04-17 15:44:24

标签: python django

当我提交一个包含用户信息(用户名,电子邮件,密码)和用户个人资料(名字和姓氏)的注册表单时,请调用form.save()profileform.save()之类的保存我的views.py然后一切似乎都很好,我没有错误。

然而,当我进入Django Admin时,我发现用户个人资料和个人资料已单独保存。

enter image description here

所以有两个不同的配置文件,一个包含我在表单中输入的用户名,另一个包含名字和姓氏(如图像所示)。

这是我的views.py:

def signup(request):
    if request.method == 'POST':
        form = UserRegistrationForm(data=request.POST)
        profileform = UserRegistrationProfileForm(data=request.POST)
        if form.is_valid() and profileform.is_valid():
            user = form.save()
            profileform.save()
            if user is not None:
                if user.is_active:
                    user_login(request, user, backend='django.contrib.auth.backends.ModelBackend')
                    return redirect('/dashboard/')
    else:
        form = UserRegistrationForm()
        profileform = UserRegistrationProfileForm()
    return render(request, 'signup-user.html', {'form': form, 'profileform': profileform})

Forms.py(对于表单的配置文件部分):

class UserRegistrationProfileForm(forms.ModelForm):
    user_fname = forms.CharField(#)
    user_lname = forms.CharField(#)

    class Meta:
        model = UserProfileModel
        fields = ['user_fname', 'user_lname']

    def clean(self):
        #...

    def save(self, commit=True):
        profile = super(UserRegistrationProfileForm, self).save(commit=False)
        if commit:
            profile.save()
        return profile

Models.py(对于配置文件,包括接收器信号):

class UserProfileModel(models.Model): # For the Company Employees
    user = models.OneToOneField(UserModel, related_name='userprofilemodel', on_delete=models.CASCADE, blank=True, null=True)
    user_fname = models.CharField(max_length=30, verbose_name='First Names')
    user_lname = models.CharField(max_length=30, verbose_name='Last Name')

    class Meta:
        verbose_name = 'Profile'

    def __unicode__(self):
        #...

    def save(self, *args, **kwargs):
        super(UserProfileModel, self).save(*args, **kwargs)

    @receiver(post_save, sender=UserModel)
    def create_user_profile(sender, instance, created, **kwargs):
        if created:
            UserProfileModel.objects.create(user=instance)

    @receiver(post_save, sender=UserModel)
    def save_user_profile(sender, instance, **kwargs):
        instance.userprofilemodel.save()

我不确定我做错了什么?我希望表单创建一个用户配置文件,用户实例作为用户,以及名字和姓氏。

关于我哪里出错的任何想法?

更新

这是UserRegistrationForm类:

class UserRegistrationForm(forms.ModelForm):
    #

    class Meta:
        model = UserModel
        fields = ['related_company_slug', 'username', 'user_email', 'password', 'passwordrepeat']

    def clean(self):
        #

    def save(self, commit=True):
        self.check_company
        user = super(UserRegistrationForm, self).save(commit=False)
        user.set_password(self.cleaned_data.get('password'))
        user.is_active = True
        if commit:
            user.save()
        return user

2 个答案:

答案 0 :(得分:1)

你应该摆脱那些信号。它们没有任何用处,可能是重复的原因。

相反,您需要做一些事情来告诉表单您正在创建的配置文件属于您刚刚创建的用户:

user = form.save()
profile = profileform.save(commit=False)
profile.user = user
profile.save()

你还应该去除表单和模型上的save方法 - 定义一个重写方法是没有意义的,它的唯一操作就是调用super方法。

同样,您可以摆脱对user is not Noneuser.is_active的检查;你知道用户存在且处于活动状态,因为你刚刚创建了它。

答案 1 :(得分:0)

在实践中,imo,最好始终为每个用户提供个人资料。要实现这种后置/预保存信号,请使用它。例如,当用户刚刚在系统中注册时,将为新用户的配置文件进行自动处理 代码将非常简单:

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    # your fields

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)

此外,如果您已经拥有没有配置文件的用户池,并且想要为其创建配置文件,则可以使用数据迁移,如果您需要此类数据迁移的代码,请参阅post in my blog