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

时间:2015-11-21 19:47:41

标签: python django django-models django-forms

在我的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_activedate_joined已定义。

就好像我的字段passwordusername被删除一样。

正如代码中的评论所述,如果我评论MyUser.save()(由OneToOneField链接到MyUser的模型User),User中的字段正确填充(但链接的模型MyUser显然是空的)

2 个答案:

答案 0 :(得分:2)

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

你不应该这样做。如果你想创建一个关系,那就这样做:删除继承,分别按照你的代码创建实例,一切正常。

答案 1 :(得分:0)

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