繁体   English   中英

Django-用户和用户个人资料表单创建两个个人资料,而不是一个

[英]Django - User and User Profile form creating two profiles instead of one

当我提交包含用户信息(用户名,电子邮件,密码)和用户个人资料(名字和姓氏)的form.save() profileform.save()在我的视图中调用form.save()profileform.save()类的保存。 py然后一切似乎都很好,我没有任何错误。

但是,当我进入Django Admin时,我看到用户个人资料和个人资料已分别保存。

在此处输入图片说明

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

这是我的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

您应该摆脱那些信号。 它们无济于事,可能是造成重复的原因。

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

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

您还应该摆脱表单和模型上的save方法-定义一个唯一的动作是调用super方法的重写方法毫无意义。

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

实际上,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)

另外,如果您已经有没有配置文件的用户池,并且想要为他们创建配置文件,则可以使用数据迁移,如果您需要用于此类数据迁移的代码,请参阅我的博客中的文章

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM