【问题标题】:why some fields are not saved in a OneToOneField model?为什么有些字段没有保存在 OneToOneField 模型中?
【发布时间】:2015-11-21 19:47:41
【问题描述】:

在我的 models.py 中,我扩展了 User 模型,这要归功于 OneToOneField:

class MyUser(User):
    user = models.OneToOneField(User, primary_key=True)
    # Extra fields:
    favourite_colour = models.CharField(max_length=100, blank=False, null=False)

    def __str__(self):
        return self.user.username

然后,在 views.py 中,我尝试从表单中保存:

 def register(request):
     if request.POST:
         form = UserForm(request.POST)
         if form.is_valid(): 
             username = form.cleaned_data['username']
             password = form.cleaned_data['password']
             favourite_colour = form.cleaned_data['favourite_colour']
             new_user = User.objects.create_user(username=username, password=password)
             new_user.save()
             new_myuser = MyUser(user=new_user)
             new_myuser.favourite_colour = favourite_colour
             # IF I COMMENT OUT THE LINE BELOW, the fields of User are correctly saved
             new_myuser.save()

             # TESTING WHETHER IT'S SAVED :
             print("{} was saved in User, with username = {}".format(new_user, new_user.username))

             return HttpResponseRedirect(reverse('home'))
        else:
            # display the page with the errors
            return render(request, 'registration/registration_form.html', {'form': form})
    else:
        # display the blank form:
        form = UserForm()
        return render(request, 'registration/registration_form.html', {'form': form})

如果我用一个简单的表格来测试它,我会得到: person1 was saved in User, with username = person1.

但是如果我检查我的数据库(db.sqlite3),创建的对象没有用户名或密码,只有idis_superuseris_staffis_activedate_joined 被定义。

就好像我的字段 passwordusername 之后被删除了。

如代码内注释中所述,如果我注释掉 MyUser.save()(模型 MyUser 通过 OneToOneField 链接到 User),则 User 内的字段已正确填充(但链接模型MyUser 显然是空的)

【问题讨论】:

  • 你还应该检查form.cleaned_data['username']form.cleaned_data['password']是否存在,然后在new_user.save()之后检查new_user是否有usernamepassword设置正确。

标签: python django django-models django-forms


【解决方案1】:

您在这里混淆了两个概念:继承和关系。您已将 MyUser 声明为从 User 继承;这意味着它会自动从用户那里获得所有字段。但是您定义了与 User 类的关系;该关系中的 User 实例与您从中继承的实例不同。

你不应该这样做。如果您想创建关系,请执行以下操作:删除继承,像您的代码一样单独创建实例,一切正常。

【讨论】:

    【解决方案2】:

    @Daniel Roseman 是正确的。如果你想扩展你的用户模型,你应该创建一个具有一对一关系的UserProfile 模型。这是一个常见的模式:

    models.py

    class UserProfile(models.Model):
        user = models.OneToOneField(User, relate_name='userprofile')
        favourite_colour = models.CharField(max_length=100, blank=False, null=False)
    
        def __str__(self):
            return self.user.username
    
    def get_or_create_profile(user):
        profile, created = UserProfile.objects.get_or_create(user=user)
        return profile
    
    User.userprofile = property(get_or_create_profile)
    

    views.py

     def register(request):
         if request.POST:
             form = UserForm(request.POST)
             if form.is_valid(): 
                 username = form.cleaned_data['username']
                 password = form.cleaned_data['password']
                 favourite_colour = form.cleaned_data['favourite_colour']
                 user = User.objects.create_user(username=username, password=password)
    
                 userprofile, created = UserProfile.objects.get_or_create(user=user)
                 if created:
                     userprofile.favourite_colour = favourite_colour
                     userprofile.save()
                 else:
                     print '... User/UserProfile already exists! Handle that here...'
    
                 return HttpResponseRedirect(reverse('home'))
            else:
                # display the page with the errors
                return render(request, 'registration/registration_form.html', {'form': form})
        else:
            # display the blank form:
            form = UserForm()
            return render(request, 'registration/registration_form.html', {'form': form})
    

    【讨论】:

      猜你喜欢
      • 2017-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-29
      • 2014-10-31
      • 2010-11-11
      • 1970-01-01
      相关资源
      最近更新 更多