我有一个扩展User
的类,以便我也可以存储物理地址。
from django.contrib.auth.models import User
class CustomUser(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
street = models.CharField(max_length=80, default="")
post_name = models.CharField(max_length=80, default=None)
post_number = models.IntegerField(default=None)
sqlite数据库中的模型包含列:
frontend_customuser:
id
street
user_id # not sure how this is created, concat of CustomUser and User fields?
post_name
post_number
我有一个表单,可让用户修改User
和CustomUser
中的数据,如下所示:
class BasicUserSettingsForm(forms.ModelForm):
class Meta:
model = User
fields = ['first_name', 'last_name', 'email']
class CustomUserSettingsForm(forms.ModelForm):
class Meta:
model = CustomUser
fields = ['street', 'post_name', 'post_number']
在views.py
我尝试显示/写入DB,如下所示。我能够显示和修改User
表,但无法触及由CustomUser
管理的(因为空的)表格(我得到的错误是NOT NULL constraint failed: frontend_customuser.user_id
)。关于我可能做错的任何提示?是否有更简单的方式通过CustomUser
(因为它只扩展User
)来编写所有这些数据?
def settings(request):
# Prepare data to be filled into forms. User should always exist so no try/except call.
prefill_user = User.objects.get(pk=request.user.id)
# In case CustomUser table is empty, instantiate a CustomUser with request.user.id user_id.
try:
prefill_customuser = CustomUser.objects.get(pk=request.user.id)
except ObjectDoesNotExist:
prefill_customuser = CustomUser(user_id=request.user.id)
if request.method == "GET":
# If CustomUser table is empty, fields will appear empty. If prefill_customuser is successful
# at retrieving data, I expect this to be populated by values from the database.
settings_form_user = BasicUserSettingsForm(initial={'first_name': prefill_user.first_name,
'last_name': prefill_user.last_name,
'email': prefill_user.email},
instance=prefill_user)
settings_form_customuser = CustomUserSettingsForm(initial={'street': prefill_customuser.street,
'post_name': prefill_customuser.post_name,
'post_number': prefill_customuser.post_number},
instance=prefill_customuser)
if request.method == "POST":
settings_form_user = BasicUserSettingsForm(request.POST, instance=prefill_user)
try:
customuser_instance = CustomUser.objects.get(pk=request.user.id)
settings_form_customuser = CustomUserSettingsForm(request.POST, instance=customuser_instance)
except ObjectDoesNotExist:
settings_form_customuser = CustomUserSettingsForm(request.POST)
if settings_form_user.is_valid() and settings_form_customuser.is_valid():
settings_form_user.save()
settings_form_customuser.save()
else:
settings_form_user = BasicUserSettingsForm(request.POST)
settings_form_customuser = CustomUserSettingsForm(request.POST)
return render(request, 'frontend/nastavitve.html',
{'settings_form_user': settings_form_user, 'settings_form_customuser': settings_form_customuser})
答案 0 :(得分:0)
使用OneToOne
字段为基本Django User
模型创建自定义用户的方式很旧。在你的情况下你需要扩展AbstractUser
,它可以从Django 1.8开始使用:
class CustomUser(AbstractUser):
street = models.CharField(max_length=80, default="")
post_name = models.CharField(max_length=80, default=None)
并将新用户加入settings.py
:
AUTH_USER_MODEL = <app_name>.CustomUser
如果要为基本用户模型添加aditional字段,则此方法有效。如果您想要覆盖它更复杂,则需要退出AbstractBaseUser
答案 1 :(得分:0)
起初我认为扩展User
类将是最优雅的解决方案,但是我可能没有做正确的事情。目前,我已经选择了一个单独的表,其中ForeignKey
链接到User
表。下面描述的实现现在将输入的值输入到表单中,在数据库中记录/更新表,并以表格形式提供最新数据。
# --models.py
class UserAddress(models.Model):
id = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
street = models.CharField(max_length=80, default="")
# post = models.ForeignKey(PostNameNum, on_delete=models.CASCADE)
post_name = models.CharField(max_length=80, default=None)
post_number = models.IntegerField(default=None)
# --forms.py
class BasicUserSettingsForm(forms.ModelForm):
class Meta:
model = User
fields = ['first_name', 'last_name', 'email']
class UserAddressSettingsForm(forms.ModelForm):
class Meta:
model = UserAddress
fields = ['street', 'post_name', 'post_number']
# --views.py
def settings(request):
# Prepare data to be filled into forms. User should always exist so no try/except call.
prefill_user = User.objects.get(pk=request.user.id)
# In case CustomUser table is empty, instantiate a CustomUser with request.user.id user_id.
try:
prefill_customuser = UserAddress.objects.get(pk=request.user.id)
except ObjectDoesNotExist:
prefill_customuser = UserAddress(id=User(id=request.user.id))
if request.method == "GET":
settings_form_user = BasicUserSettingsForm(initial={'first_name': prefill_user.first_name,
'last_name': prefill_user.last_name,
'email': prefill_user.email},
instance=prefill_user)
settings_form_customuser = UserAddressSettingsForm(initial={'street': prefill_customuser.street,
'post_name': prefill_customuser.post_name,
'post_number': prefill_customuser.post_number},
instance=prefill_customuser)
if request.method == "POST":
settings_form_user = BasicUserSettingsForm(request.POST, instance=prefill_user)
try:
settings_form_customuser = UserAddressSettingsForm(request.POST, instance=prefill_customuser)
except ObjectDoesNotExist:
settings_form_customuser = UserAddressSettingsForm(request.POST)
# if settings_form_user.is_valid() and settings_form_customuser.is_valid():
if settings_form_customuser.is_valid():
settings_form_user.save()
settings_form_customuser.save()
else:
settings_form_user = BasicUserSettingsForm(request.POST)
settings_form_customuser = UserAddressSettingsForm(request.POST)
return render(request, 'frontend/nastavitve.html',
{'settings_form_user': settings_form_user,
'settings_form_customuser': settings_form_customuser}
)