无法为不同的用户类型显示不同的表单

时间:2018-02-07 16:35:11

标签: python django

我有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)




2 个答案:

答案 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,则表示您的用户是TeacherStudent

如果这不是预期的行为,您必须确保您的应用程序不会让它发生。否则,您需要两个单独的视图(或至少两个网址),一个用于修改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})

上述代码正在考虑以下假设:

  • StudentTeacher模型与pastebin url;
  • 中所述相同
  • 用户可以是StudentTeacher,但不能同时使用。{/ li>

答案 1 :(得分:0)

可能的原因之一是,您需要在开头为变量s指定默认的False值:

@login_required
def profile_edit(request):
    s = False
    user = request.user

但是在所有情况下,您需要确保数据库的一致性。我的意思是你可能在学生和老师中都有一个用户(request.user);小心。