我有2种用户类型,老师和学生。我构建了视图以便能够编辑学生档案。但我也需要一个不同的老师。我不想要2个观点,因为那是毫无意义的。现在,对于老师来说,它按预期工作,但由于某些原因,教师会显示与学生相同的形式......教师具有不同的属性,因此它需要显示不同的形式。
class TeacherEditForm(forms.ModelForm):
email = forms.EmailField(required=False)
name = forms.CharField(max_length=30, required=False)
surname = forms.CharField(max_length=50, required=False)
academic_title = forms.CharField(max_length=30, required=False)
bio = forms.Textarea()
website = forms.URLField(required=False)
photo = forms.ImageField(required=False)
phone = forms.CharField(required=False)
class StudentEditForm(forms.ModelForm):
email = forms.EmailField(required=False)
name = forms.CharField(max_length=30)
surname = forms.CharField(max_length=50)
photo = forms.ImageField(required=False)
phone = forms.CharField(max_length=15, required=False)

@login_required
def profile_edit(request):
user = request.user
try:
student = Student.objects.get(user=user)
s = True
except ValueError:
teacher = Teacher.objects.get(user=user)
if not s:
if request.method != 'POST':
form = TeacherEditForm(instance=teacher)
else:
form = TeacherEditForm(request.POST, instance=teacher)
if form.is_valid():
user.email = form.cleaned_data['email']
user.save()
form.save()
return redirect('index')
elif s:
if request.method != 'POST':
form = StudentEditForm(instance=student)
else:
form = StudentEditForm(request.POST, instance=student)
if form.is_valid():
user.email = form.cleaned_data['email']
user.save()
form.save()
return redirect('index')
context = {
"form": form,
}
return render(request, "registration/profile_edit.html", context)

答案 0 :(得分:1)
您的代码始终使用StudentEditForm
的唯一原因是request.user
始终与Student
实例相关联。
考虑到用户是Teacher
并且与Student
模型没有关系的情况,您的代码会引发异常。正如abahnihi所提到的,你应该抓住ObjectDoesNotExist
例外而不是ValueError
:
try:
student = Student.objects.get(user=user)
s = True
except Student.DoesNotExist:
teacher = Teacher.objects.get(user=user)
实现所需行为的最佳方法是编写单元测试。
在任何情况下,只是为了确保问题所在,快速进行调试"在视图顶部使用print
语句:
@login_required
def profile_edit(request):
print(request.user.student_id)
print(request.user.teacher_id)
#... rest of your view
如果您在控制台上获得了两个ID,则表示您的用户是Teacher
和Student
。
如果这不是预期的行为,您必须确保您的应用程序不会让它发生。否则,您需要两个单独的视图(或至少两个网址),一个用于修改Student
个人资料,另一个用于修改Teacher
个人资料。
无论如何,以下是改善观点的方法:
from django.db import transaction
@login_required
def profile_edit(request):
user = request.user
if hasattr(user, 'student') and isinstance(user.student, Student):
form_class = StudentEditForm
profile_model = user.student # reverse relationship via OneToOne link
else:
form_class = TeacherEditForm
profile_model = user.teacher
if request.method == 'POST':
form = form_class(request.POST, instance=profile_model)
if form.is_valid():
with transaction.atomic(): # two database operations, wrap in a transaction for consistency
profile_model = form.save()
user.email = profile_model.email
user.save()
return redirect('index')
else:
form = form_class(instance=profile_model)
return render(request, 'registration/profile_edit.html', {'form': form})
上述代码正在考虑以下假设:
Student
和Teacher
模型与pastebin url; Student
或Teacher
,但不能同时使用。{/ li>
答案 1 :(得分:0)
可能的原因之一是,您需要在开头为变量s指定默认的False值:
@login_required
def profile_edit(request):
s = False
user = request.user
但是在所有情况下,您需要确保数据库的一致性。我的意思是你可能在学生和老师中都有一个用户(request.user);小心。