为什么有些字段没有保存在 OneToOneField 模型中?

why some fields are not saved in a OneToOneField model?

在我的 models.py 中,我正在扩展用户模型,感谢 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_active, date_joined 已定义。

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

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

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

你不应该这样做。如果你想创建一个关系,那么就这样做:删除继承,像你的代码已经做的那样单独创建实例,一切正常。

@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})