Django从已过滤的外键对象中过滤对象

时间:2020-05-21 07:10:17

标签: python django

我正在尝试过滤与具有称为“内容”模型的外键关系的讲座列表。基本上,每个讲座都与特定的内容有关。但是我被困住了。下面是我的代码:

models.py

class CourseContent(models.Model):
    title = models.CharField(max_length = 250)
    course = models.ForeignKey(Course, on_delete = models.CASCADE, null = True)

    def __str__(self):
        return self.title

class CourseLecture(models.Model):
    content = models.ForeignKey(CourseContent, on_delete = models.CASCADE, null = True)
    title = models.CharField(max_length = 50)
    file = models.FileField()

    def __str__(self):
        return self.title

views.py

def coursedetails(request, pk):
    course = Course.objects.get(id = pk)
    content = CourseContent.objects.filter(course = course)
    content_ids = content.values_list('id')
    lectures = CourseLecture.objects.filter(content__in = content_ids)
    reviews = course.review_set.all()
    rev_count = reviews.count()
    avg = reviews.aggregate(avg = Avg('rating'))
    total = reviews.aggregate(sum = Sum('rating'))
    print(content_ids)
    return render(request, "main/course_detail_view.html", {"course": course, "lectures": lectures, "content": content , "reviews": reviews, "rev_count": rev_count, "avg": avg, "total": total})

这里的问题是我无法根据特定的内容ID过滤讲座。过滤的对象显示在所有内容中,而不显示在其特定部分。

谢谢。

3 个答案:

答案 0 :(得分:1)

上面的实现应该可以,但是效率不高。这是我的做法:

lectures = CourseLecture.objects.filter(content__course_id = pk)

如果您打算按content_id订购讲座,则只需添加order_by

lectures = CourseLecture.objects.filter(content__course_id = pk).order_by('content')

最后,如果要显示有关每种内容的讲座,则可以使用以下模板代码:

{% for c in content %}
    {{ c.title }}
    {% for lecture in c.courselecture_set.all %}
       {{ lecture.title }}
     {% endfor %}
{% endfor %}

答案 1 :(得分:0)

尝试将其替换为

lectures = CourseLecture.objects.filter(content__pk__in = content_ids)

请参见此Django: What is the correct way to query by foreign key field's id?

答案 2 :(得分:0)

您可以在外键中使用related_name。 因此,它将像:

然后您可以只使用Course.lecture.all()。它将为您提供带有该课程外键的所有讲座。

例如:

class Airport(models.Model):
    city = models.CharField(max_length=64)
    code = models.CharField(max_length=4)

class Flights(models.Model):
    origin = models.ForeignKey(Airport, on_delete=models.PROTECT, related_name="origin")
    destination= models.ForeignKey(Airport, on_delete=models.PROTECT, related_name="destination")
    duration = models.IntegerField()

因此,Airport.objects.get(pk=1).origin.all()将给我所有来自机场的,具有主键1的航班。

希望这会有所帮助。

相关问题