Django - 数据库查询 - 检查值列表是否是另一个列表的子集

Django - Database querying - Checking if a list of values is a subset of another list

我正在编写一个旨在教授语言的网站。这个想法是,通过验证课程,学生们正在解锁其他内容(练习、歌曲……)。正式地,每节课都附有 标签 。每当学生验证课程时,他们都会验证关联的 标签 。每个内容都标有与这些标签对应的先决条件。

在一个页面上,我想根据用户解锁的标签显示用户可以访问的所有歌曲。如果他们解锁了与歌曲关联的所有标签,则可以查看;否则他们不能。

这是一节课的模型(名为课程):

class Cours(models.Model):
    niveau=models.ForeignKey(Niveau,on_delete=models.CASCADE)
    titre=models.CharField(max_length=255, unique=True)
    tags=models.ManyToManyField(Tag)

这是一首歌的模型:

class Chanson(models.Model):
    titre=models.CharField(max_length=255, unique=True)
    prerequis=models.ManyToManyField(Tag,blank=True,related_name="+")

这是用户配置文件的模型以及我发现使用 Python built-in sets 来回答我的问题的解决方案。

class Profil(models.Model):
    user=models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
    cours_valides=models.ManyToManyField(Cours)
    chanson_valides=models.ManyToManyField(Chanson)

    def songs_to_do(self):
        songlist=Chanson.objects.exclude(id__in=self.chanson_valides.values_list('id',flat=True))
        outputsonglist=list()
        for song in songlist:
            if set(song.prerequis.values_list('id',flat=True))<=set(self.cours_valides.values_list('tags',flat=True)):
                outputsonglist.append(song)
        return outputsonglist

要做的歌曲 方法基本上是 returns 用户尚未涵盖但可以根据他们目前已验证的课程访问的歌曲列表。实际上,cours valides 字段列出了用户验证的所有课程,而 chansons valides 字段列出了用户已经翻唱的所有歌曲。

我想知道是否有更有效的方法来处理此类问题?

我会执行 2 个查询:

获取用户不拥有的所有标签:

locked_tags = Tag.objects.exclude(cours__profil=self)

找出用户尚未解锁标签的所有歌曲:

unlocked_songs = Chanson.objects.exclude(prerequis__in=locked_tags)

您的代码如下所示:

class Profil(models.Model):
    user=models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
    cours_valides=models.ManyToManyField(Cours)
    chanson_valides=models.ManyToManyField(Chanson)

    def unlocked_songs(self):
        locked_tags = Tag.objects.exclude(cours__profil=self)
        return Chanson.objects.exclude(prerequis__in=locked_tags)