使用OneToOne字段和用户模型创建用户配置文件页面 [英] Creating a User Profile page using OneToOne field with User Model

查看:109
本文介绍了使用OneToOne字段和用户模型创建用户配置文件页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我有一个Teacher字段,它使用OneToOne字段扩展了User Model。



模型。 py

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

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



forms.py

 类UserForm(forms.ModelForm):
类Meta:
模型=用户
字段=('first_name','last_name','email')

类TeacherForm (forms.ModelForm):
类元:
模型=教师
字段=('availability','bio','teacher_logo')

views.py

  @login_required 
@ transaction.atomic
def update_profile(request):
如果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()和Teacher_form.is_valid( ):
user_form.save()
Teacher_form.save()
messages.success(request,_('您的个人资料已成功更新!'))
return redirect('用户:index')
其他:
messages.error(请求,_('请更正以下错误。'))
其他:
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
})

为我们模板ers / profile.html

 < form method = post> 
{%csrf_token%}
{{user_form.as_p}}
{{Teacher_form.as_p}}
< button type = submit>保存更改< / button> ;
< / form>

urls.py

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

我可以使用更新视图,但是随后我需要在URL中指定,这似乎是不正确的方式。同样,用户也可以编辑其他用户的个人资料。



当我执行上述操作时,我抱怨用户对象没有属性老师。 / p>

当我从 TeacherForm(instance = request.user.teacher)<< c $ c> .teacher 中删除​​它使用表单加载页面,但是当我更新时,它仍然给我同样的抱怨(在views.py的两个地方都删除了)



编辑:models.py extra

  @receiver(post_save,sender = User)
def create_user_profile(发件人,实例,创建的,**假的):
如果创建的话:
Teacher.objects.create(user = instance)

@receiver(post_save,sender =用户)
def save_user_profile(发件人,实例,** kwargs):
实例.eacher.save()


解决方案

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

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

或更好地设置 related_name 到老师

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


I'm currently using Django all-auth, and it has a /accounts/profile page which I want to create/populate with a form which updates user information.

I have a Teacher field, which extends the User Model using OneToOne field.

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()

This teacher model is what I want the user to update in /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
    })

template users/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')

I can use an update view, but then I need to specify in the URL, which seems an incorrect way of doing it; Also, users will be able to edit someone else profiles.

When I run the above, I get a complaint that 'User' object has no attribute 'teacher'.

When I remove .teacher from TeacherForm(instance=request.user.teacher) It loads the page with the form, but when I update, it still gives me the same complaint (removed in both places in views.py)

EDIT: 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()

解决方案

you set related name as Teacher, so you need:

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

or better set related_name to 'teacher'

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

这篇关于使用OneToOne字段和用户模型创建用户配置文件页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆