Django扩展用户模型问题:自定义属性无法显示
看起来你是在Django里扩展User模型做用户认证系统时,碰到了自定义Profile字段无法在编辑页面显示/保存的问题对吧?我之前做项目时也踩过这个坑,给你几个关键的排查和解决步骤:
1. 自定义表单,把Profile字段加进去
默认的UserChangeForm只处理原生User模型的字段,根本不知道你新增的salutation、title这些Profile属性。你得自己写一个包含这些字段的表单:
from django.contrib.auth.forms import UserChangeForm from django import forms from .models import Profile class CustomUserEditForm(UserChangeForm): # 添加上你的自定义字段 salutation = forms.CharField(max_length=100, required=False, label="称呼") title = forms.CharField(max_length=100, required=False, label="职位") class Meta: model = User fields = ('username', 'email', 'first_name', 'last_name') # 保留原生User需要的字段 def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 如果用户已经有Profile实例,就把现有值填充到表单里 if self.instance.pk: profile = self.instance.profile self.fields['salutation'].initial = profile.salutation self.fields['title'].initial = profile.title def save(self, commit=True): # 先保存User模型的变更 user = super().save(commit=False) if commit: user.save() # 获取或创建用户的Profile(避免新用户没有Profile的情况) profile, _ = Profile.objects.get_or_create(user=user) # 更新Profile的自定义字段 profile.salutation = self.cleaned_data['salutation'] profile.title = self.cleaned_data['title'] profile.save() return user
2. 确保post_save信号能自动创建Profile
你代码里的信号接收器可能没写全,得确保新用户注册时自动生成对应的Profile,不然编辑时会找不到关联实例:
from django.db.models.signals import post_save from django.dispatch import receiver from django.contrib.auth.models import User from .models import Profile @receiver(post_save, sender=User) def create_user_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance) @receiver(post_save, sender=User) def save_user_profile(sender, instance, **kwargs): instance.profile.save()
另外要注意:Django 2.0+版本里,OneToOneField必须指定on_delete参数,所以你的Profile模型要修正:
class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) # 加上on_delete salutation = models.CharField(max_length=100, default='') title = models.CharField(max_length=100, default='') # 补全max_length
3. 在视图里用自定义表单
不管你是用函数视图还是类视图,都要把默认的表单替换成你刚才写的CustomUserEditForm。比如用类视图的例子:
from django.contrib.auth.views import UserUpdateView from django.urls import reverse_lazy from .forms import CustomUserEditForm class UserProfileEditView(UserUpdateView): form_class = CustomUserEditForm template_name = 'accounts/edit_profile.html' # 你的编辑页面模板 success_url = reverse_lazy('profile') # 保存后跳转的页面
4. 模板里要渲染自定义字段
最后一步,别忘记在编辑页面的模板里把这些新字段展示出来,不然用户根本看不到输入框:
<form method="post"> {% csrf_token %} <!-- 先渲染原生User的字段 --> <div class="form-group"> {{ form.username.label_tag }} {{ form.username }} </div> <div class="form-group"> {{ form.email.label_tag }} {{ form.email }} </div> <!-- 再加上你的自定义Profile字段 --> <div class="form-group"> {{ form.salutation.label_tag }} {{ form.salutation }} </div> <div class="form-group"> {{ form.title.label_tag }} {{ form.title }} </div> <button type="submit" class="btn btn-primary">保存修改</button> </form>
按这几步走,你的自定义字段应该就能正常显示和保存了。
内容的提问来源于stack exchange,提问作者InventoryGuy
相关产品推荐
相关产品推荐

