RelatedObjectDoesNotExist异常

时间:2017-05-20 13:57:45

标签: django django-models django-views

我尝试在用户中定义签名前缀,但我得到了此异常RelatedObjectDoesNotExist。事情是django找不到用户学生和家长(例外值:用户没有学生)

我想根据用户的类型

呈现不同的模板

models.py

from django.db import models
from django.contrib.auth.models import User


# Create your models here.


class Teacher(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    prefix = 't'

    def __str__(self):
        return self.user.first_name + ' ' + self.user.last_name


class Student(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    parent = models.ForeignKey('Parent', null=True)
    prefix = 's'

    def __str__(self):
        return self.user.first_name + ' ' + self.user.last_name


class Parent(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    prefix = 'p'

    def __str__(self):
        return self.user.first_name + ' ' + self.user.last_name

views.py

def sign_in(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        user_login = User.objects.get(username=username)
        user = authenticate(username=username, password=password)
        if user is not None:
            login(request, user_login)
            if user_login.student.prefix == 'S':
                return render(request, 's.html')
            if user_login.teacher.prefix == 'T':
                return render(request, 't.html')
            if user_login.parent.prefix == 'P':
                return render(request, 'p.html')
        else:
            return render(request, 'index.html', {'error': True})
    else:
        return render(request, 'index.html')
System check identified no issues (0 silenced).
May 20, 2017 - 21:43:51
Django version 1.11.1, using settings 'e_diary.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
[20/May/2017 21:43:56] "GET / HTTP/1.1" 200 983
Internal Server Error: /sign_in/
Traceback (most recent call last):
  File "C:\Users\USER\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
    response = get_response(request)
  File "C:\Users\USER\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Users\USER\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\USER\Desktop\e_diary\electronic_diary\views.py", line 29, in sign_in
    if user_login.teacher.prefix == 'T':
  File "C:\Users\USER\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\fields\related_descriptors.py", line 406, in __get__
    self.related.get_accessor_name()
django.db.models.fields.related_descriptors.RelatedObjectDoesNotExist: User has no teacher.
[20/May/2017 21:44:02] "POST /sign_in/ HTTP/1.1" 500 70872

1 个答案:

答案 0 :(得分:2)

您可以在Student,Teacher表中为字段用户设置related_name,如下所示

user = models.OneToOneField(User, related_name='student')

此外,您需要确保为用户创建相应的学生,父母,模型。

此外,您正在检查大写字母的前缀,在模型中它们是小写字母。 Python严格区分大小写。

我认为你也需要改变if语句,

try:
    if user_login.student.prefix == 'S'
        return render(request, 's.html')
except:
    try:
        if user_login.teacher.prefix == 'T'
            return render(request, 't.html')
    except:
        if user_login.parent.prefix == 'P':
            return render(request, 'p.html')

因为,在您的视图中,在视图中遇到每个 if语句。然后,如果用户是教师,那么它没有学生对象。然后,Django引发错误。因此,最好使用try-except组合。

另外,根据您的代码,我想出了关于学生,教师,家长模型的建议。 您可以使用单个模型配置文件,其中包含两个标志is_teacher,is_parent和一个默认的null ForeignKey字段,仅在is_parent标志为True时设置,而不是在数据库中重复创建表。 但是,这只是一个建议,因为在你的方法中,学生,教师,家长可以很容易地区分,虽然它占用更多的存储空间。