Reputation: 409
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()
Upvotes: 0
Views: 2951
Reputation:
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')
# ^^^
Upvotes: 1