使用带用户模型的OneToOne字段创建用户配置文件页面

时间:2017-08-29 09:58:25

标签: django django-models django-forms django-views

我目前正在使用Django all-auth,它有一个/ accounts / profile页面,我想创建/填充一个更新用户信息的表单。

我有一个教师字段,它使用OneToOne字段扩展用户模型。

models.py

class Teacher(models.Model):
    user = models.OneToOneField(User, on_delete=models.PROTECT, related_name='Teacher')
    bio = models.TextField(max_length=500, blank=True)
    availability = models.BooleanField(default=False)
    teacher_logo = models.FileField()

我希望用户在/ accounts / profile中更新此教师模型。

forms.py

class UserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'email')

class TeacherForm(forms.ModelForm):
    class Meta:
        model = Teacher
        fields = ('availability', 'bio','teacher_logo')

views.py

@login_required
@transaction.atomic
def update_profile(request):
    if request.method == 'POST':
        user_form = UserForm(request.POST, instance=request.user)
        teacher_form = TeacherForm(request.POST, instance=request.user.teacher)
        if user_form.is_valid() and teacher_form.is_valid():
            user_form.save()
            teacher_form.save()
            messages.success(request, _('Your profile was successfully updated!'))
            return redirect('users:index')
        else:
            messages.error(request, _('Please correct the error below.'))
    else:
        user_form = UserForm(instance=request.user)
        teacher_form = TeacherForm(instance=request.user.teacher)
    return render(request, 'accounts/profile.html', {
        'user_form': user_form,
        'teacher_form': teacher_form
    })

模板用户/ profile.html

<form method="post">
  {% csrf_token %}
  {{ user_form.as_p }}
  {{ teacher_form.as_p }}
  <button type="submit">Save changes</button>
</form>

urls.py

url(r'^profile/$', views.update_profile, name='Update-Profile')

我可以使用更新视图,但是我需要在URL中指定,这似乎是一种不正确的方式;此外,用户还可以编辑其他个人资料。

当我执行上述操作时,我得到的投诉是“用户”对象没有属性“老师”。

当我从.teacher移除TeacherForm(instance=request.user.teacher)时,它会加载带有表单的页面,但是当我更新时,它仍然会给我相同的投诉(在views.py中的两个位置都删除)

编辑:models.py extra

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        Teacher.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    instance.Teacher.save()

1 个答案:

答案 0 :(得分:1)

您将相关名称设为Teacher,因此您需要:

teacher_form = TeacherForm(instance=request.user.Teacher)
#                                               ^^^^

或更好地将related_name设为“老师”

class Teacher(models.Model):
     user = models.OneToOneField(
         User, 
         on_delete=models.PROTECT,
         related_name='teacher')
#                     ^^^