为什么有些字段没有保存在 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),创建的对象没有用户名或密码,只有id
、is_superuser
、is_staff
、is_active
, date_joined
已定义。
好像我的字段 password
和 username
之后被删除了。
如代码中的注释所述,如果我注释掉 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})
在我的 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),创建的对象没有用户名或密码,只有id
、is_superuser
、is_staff
、is_active
, date_joined
已定义。
好像我的字段 password
和 username
之后被删除了。
如代码中的注释所述,如果我注释掉 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})