我有2个模型,一个模型用于课程列表,另一个模型用于每个用户的注册列表。
目前,注册表的结构是每个学生只有1条记录。登记表中有一个ManytoManyField,可让我为每个学生添加多个课程。
我想确保当学生登录时,他们只看到他们已经注册的课程。我无法弄清楚视图中哪种查询最适合实现此目的。
models.py
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Course(models.Model):
title = models.CharField(max_length=255)
description = models.TextField()
created_dt = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
class Enrollment(models.Model):
student = models.ForeignKey(User,on_delete=models.CASCADE)
course = models.ManyToManyField(Course)
def __str__(self):
return f"{self.student}'s Enrollments"
views.py
from django.shortcuts import render,get_object_or_404
from django.http import HttpResponse
from .models import Course,Step,Enrollment
from django.http import Http404
from django.contrib.auth.decorators import login_required
@login_required
def course_list(request):
#courses = Course.objects.all()
courses = Course.objects.filter(id in Enrollment.objects.filter(student=request.user))
return render(request,"courses/course_list.html",{'courses':courses})
答案 0 :(得分:0)
我不确定Enrollment
的建模在这里是否有意义,因为基本上您在这里创建了一个额外的表。将Enrollment
本身视为Course
和User
之间的多对多关系会更有意义,例如:
from django.contrib.auth import get_user_model
class Course(models.Model):
title = models.CharField(max_length=255)
description = models.TextField()
created_dt = models.DateTimeField(auto_now_add=True)
enrollment = models.ManyToManyField(get_user_model())
def __str__(self):
return self.title
如果以后要为每个(课程,用户)元组指定一些额外的属性,则可以指定through
parameter [Django-doc]。
然后我们可以通过以下方式获取课程列表:
@login_required
def course_list(request):
courses = Course.objects.filter(enrollment=request.user)
return render(request,"courses/course_list.html", {'courses':courses})
如果您继续使用原始建模,我们可以使用:
@login_required
def course_list(request):
courses = Course.objects.filter(enrollment__student=request.user)
return render(request,"courses/course_list.html", {'courses':courses})
但是这种建模使事情有些“复杂”。
注意:如果您引用用户模型,建议您使用
get_user_model
[Django-doc]函数而不是直接使用User
,因为如果您以后实现客户用户模型, ,那么您将很难更改所有内容。