在另一个模型的多对多关系中按分数排序查询集

时间:2017-02-25 07:47:48

标签: python django python-2.7

我的模型设置如下,每节课都属于一个章节并拥有一个所有者。对于每个章节,用户都有一个分数存储在UserChapterScore

from django.db import models

class User(models.Model):
    name = models.TextField()

class Chapter(models.Model):
    name = models.TextField()

class Lesson(models.Model):
    chapter = models.ForeignKey(Chapter)
    owner = models.ForeignKey(User)
    name = models.TextField()

 class UserChapterScore(models.Model):
     chapter = models.ForeignKey(Chapter)
     user = models.ForeignKey(User)
     score = models.IntegerField(default=0)

如何检索属于章节的课程,按照所有者的章节分数排序?

编辑:如果需要,请转换为M2M等价物。我用模型来说明模型的结构

3 个答案:

答案 0 :(得分:0)

当然可以,你可以试试这个......

from django.db import models

class Chapter(models.Model):
    name = models.TextField()

    def get_lessons(self):
        """return all lessions filtered by specific chapter"""
        return Lesson.objects.filter(chapter__pk=self.pk)


class Lesson(models.Model):
    chapter = models.ForeignKey(Chapter)
    owner = models.ForeignKey(User)
    name = models.TextField()

    def get_user_chapters(self):
        """return all chapters by specific `chapter` and `user` in this lession"""
        return UserChapterScore.objects.filter(chapter=self.chapter, user=self.owner)

    def get_user_scores(self):
        """return total scores by specific `chapter` and `user` in this lession"""
        return self.get_user_chapters().aggregate(models.Sum('score'))['score__sum']


class UserChapterScore(models.Model):
    chapter = models.ForeignKey(Chapter)
    user = models.ForeignKey(User)
    score = models.IntegerField(default=0)

更新,你可以每个人;

lessons = [{
    'lessons': chapter.get_lessons(), # return queryset of lessons
    'lessons_detail': [
        {
            'owner': c.owner, 
            'scores': c.get_user_scores(),
            'chapters': c.get_user_chapters()
        } for c in chapter.get_lessons()
    ]
} for chapter in Chapter.objects.all()]

答案 1 :(得分:0)

对于backward relationships,您可以使用<lowercase_related_model_name>_set获取相关模型。对于您的示例,您可以尝试:

Lesson.objects.fitler(chapter=chapter).order_by('chapter__userchapterscore_set__score')

答案 2 :(得分:0)

这比我想象的要简单。我需要在LessonUserUserChapterScore之间加入

  • 课程的章节是我想要列表的章节
  • 课程所有者ID和用户ID加入UserLesson表格
  • UserChapterScore表的章节应该与我想要列表的章节相同
  • UserChapterScore表和User表按两个表中的用户ID加入。

当我们在查询集过滤器中使用双下划线表示法时,我没有意识到Django会这样做。

此外,UserChapterScore表的反向访问器在userchapterscore模型中以User存在,如果是外键。

最终查询是:

Lesson.objects.filter(chapter=chapter, owner__userchapterscore__chapter=chapter).order_by('owner__userchapterscore__score)