访问通过表单上的一对一字段模型链接的模型的数据



我想要一个预先填充的表单,其中包含有关登录用户个人资料的详细信息(例如名字和姓氏(,以便他们可以更新它们。我有一个包含名字和姓氏的自定义用户模型,然后是一个链接到用户模型并对其进行扩展的配置文件模型,其中包含一些额外的信息。

我在配置文件模型中定义了一个常量,理论上应该获取用户的名字和姓氏。

models.py:

class User(AbstractBaseUser):
email = models.EmailField(verbose_name="email", unique=True, max_length=255)
first_name = models.CharField(max_length=30, blank=True, null=True)
surname = models.CharField(max_length=30, blank=True, null=True)
[...]
objects = UserManager()
[...]

已添加轮廓模型

class Profile(models.Model):
user = models.OneToOneField(User, related_name='current_user', on_delete=models.CASCADE)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
def surname(self):
return self.user.surname}
def first_name(self):
return self.user.first_name
[...]

views.py:

@login_required
def profile_edit(request):
if request.method == 'POST':
p_form = ProfileUpdateForm(request.POST, request.FILES, instance=request.user.profile)
if p_form.is_valid():
p_form.save()
messages.success(request, f'Your account has been updated')
[...]

forms.py:

class ProfileUpdateForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('first_name', 'surname')

模板.html:

{% extends "base.html" %}
{% block content %}
<div>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ p_form }}
<button class="button" type="submit"> User update</button>
</form>
</div>
{% endblock content %}

通过浏览器访问模板时,我希望看到表单中已经填充了配置文件(即用户(的名字和姓氏。相反,我在外壳中得到了一个django.core.exceptions.FieldError: Unknown field(s) (surname, first_name) specified for Profile

--

用户ruddra的答案工作正常,我已将其标记为我问题的答案。不过,声明两个不同的表单对象并在模板中打印它们也可以:

views.py:

u_form = UserUpdateForm(request.POST, instance=request.user)
p_form = ProfileUpdateForm(request.POST, request.FILES, instance=request.user.profile)

forms.py:

class UserUpdateForm(forms.ModelForm):
class Meta:
model = User
fields = ('first_name', 'surname')
class ProfileUpdateFormOld(forms.ModelForm):
class Meta:
model = Profile
fields = ('image',)

模板.html:

{{ u_form }}
{{ p_form }}

>基本上这些字段来自User模型,它们不在模型中Profile。因此,您可以将ProfileUpdateForm中的模型类更改为User

class ProfileUpdateForm(forms.ModelForm):
class Meta:
model = User
fields = ('first_name', 'surname')

根据评论更新了答案:

class ProfileUpdateForm(forms.ModelForm):
first_name = forms.CharField(max_length=255)
surname = forms.CharField(max_length=255)
def __init__(self, *args, **kwargs):
super(ProfileUpdateForm, self).__init__(*args, **kwargs)
self.initial['first_name'] = self.instance.first_name()
self.initial['surname'] = self.instance.surname()
class Meta:
model = Profile
fields = ('first_name', 'surname')
def save(self, *args, **kwargs):
user = self.instance.user
user.first_name = self.cleaned_data.get('first_name')
user.surname = self.cleaned_data.get('surname')
user.save()
return super(ProfileUpdateForm, self).save(*args, **kwargs)

覆盖__init__(...)方法的替代方法是在启动表单时发送初始数据,传递初始数据。例如: profile = request.user.profile

ProfileUpdateForm(instance=profile, initial={'first_name':profile.first_name(), 'surname': profile.surname()})