【问题标题】:Django: Extended User Model Cant SaveDjango:扩展用户模型无法保存
【发布时间】:2017-10-20 23:28:14
【问题描述】:

我已经用另一个名为 profile 的模型扩展了 django 用户模型:

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    chosenCharity = models.ForeignKey('meta.Charity', db_column='chosenCharityid', related_name='user_chosenCharity')
    bio = models.TextField(max_length=500, blank=True)
    location = models.CharField(max_length=30, blank=True)
    birth_date = models.DateField(null=True, blank=True)

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

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

当我尝试使用下面的代码在视图中创建新用户时,我收到以下错误“(1048,“Column 'chosenCharityid' cannot be null”)”:

@transaction.atomic
def register(request):
    selectedTeams = StraightredTeam.objects.filter(Q(teamid=request.session['team1id']) | Q(teamid=request.session['team2id'])).order_by('teamname')
    request.POST.get('currentCharities')

    next_url = request.POST.get('next', request.GET.get('next', reverse('straightred.payment')))
    if request.method == 'POST':
        form = RegistrationForm(request.POST)
        if form.is_valid():
            new_user = form.save()

我知道什么时候用户已经创建了我应该可以使用:

user = User.objects.get(pk=user_id)
user.profile.chosenCharity = 12
user.save()

但我不确定在创建用户时如何执行此操作。任何帮助将不胜感激。

以下是一份注册表副本,以提供帮助:

class RegistrationForm(BootstrapModelForm, UserCreationForm):
    email_opt_in = forms.BooleanField(label='Receive DWAD e-mail updates', required=False)

    def __init__(self, *args, **kwargs):
        super(RegistrationForm, self).__init__(*args, **kwargs)
        # The default Django user model doesn't require these fields to be set
        # but we do.

        self.fields['email'].required = True

    def clean_email(self):
        email = self.cleaned_data['email']
        if User.objects.filter(email__iexact=email).exists():
            raise ValidationError('There is already an account registered with this e-mail address.')
        return email

    class Meta:
        model = User
        fields = ['first_name', 'last_name', 'email', 'username']

慈善模式:

class Charity(models.Model):
    name = models.CharField(max_length=50, unique=True)
    website = models.URLField()
    enabled = models.BooleanField(default=True)

    def __unicode__(self):
        return self.name

    class Meta:
        ordering = ['name']
        verbose_name_plural = 'charities'

【问题讨论】:

  • 在 create_user_profile 信号接收器中保存配置文件对象时,chosenCharity 不能为空。个人资料需要一个慈善机构 ID。如果它是可选的,则在您所选择的Charity 字段上设置 null=True。
  • 您好 Zap,它不是可选的,但我只是不知道如何在视图中设置它。有什么想法吗?
  • request.POST 数据中是否有可用的慈善机构 ID?您可以在 new_user = form.save() 之后立即创建一个配置文件对象,而不是使用 post_save 信号
  • 我在“request.session['chosenCharityid']”中有它。但是我不能在 new_user - form.save() 之后做任何事情。你是说我唯一的选择是删除自动创建,然后直接保存配置文件?
  • 个人资料需要一个慈善机构 ID。没有简单的直接方法可以在 post_save 中提供个人资料慈善 ID。是的,您需要保存配置文件对象,您可以在其中为其提供慈善 ID。为什么form.save()之后什么都不能做?

标签: django django-forms


【解决方案1】:

不要在 post_save 信号中创建 Profile 对象。您无法在 create_user_profile 方法中访问所需的慈善机构 ID。所以删除那部分代码。

而是在您将用户对象保存在 register 视图中后立即保存配置文件对象,如下所示:

@transaction.atomic
def register(request):
    selectedTeams = StraightredTeam.objects.filter(Q(teamid=request.session['team1id']) | Q(teamid=request.session['team2id'])).order_by('teamname')
    request.POST.get('currentCharities')

    next_url = request.POST.get('next', request.GET.get('next', reverse('straightred.payment')))
    if request.method == 'POST':
        form = RegistrationForm(request.POST)
        if form.is_valid():
            new_user = form.save()
            charity_id = request.session['chosenCharityid']
            # create profile object
            Profile.objects.create(user=new_user, chosenCharity_id=charity_id)

编辑:

我看到您正在使用另一种方法save_user_profile 来接收 post_save 信号。

也不要使用它。这是一个关于做一件简单直接的事情的方法。

使用您自己的代码示例:

user = User.objects.get(pk=user_id)
# here you are assigning a new charity id to the profile object
user.profile.chosenCharity = 12
# you save the user object on which nothing has changed
# instead you should save the profile object
user.save() # no need
user.profile.save() # direct and logical

【讨论】:

  • 非常感谢您的帮助,但这只是给了我“未定义全局名称'配置文件'”。
  • 配置文件模型在哪里定义?你能检查它是否正确导入
  • 我的 Charity 模型有问题。我去解决这个问题时忽略我:(
  • 一切正常,但我仍然收到以下错误:用户没有个人资料。
  • 您在哪一行收到此错误?您是否删除了两种保存后信号方法?
猜你喜欢
  • 2016-08-16
  • 2014-09-25
  • 2016-10-12
  • 2011-02-28
  • 2013-12-06
  • 2018-01-21
  • 2012-12-15
相关资源
最近更新 更多