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)
我正在编写一个旨在教授语言的网站。这个想法是,通过验证课程,学生们正在解锁其他内容(练习、歌曲……)。正式地,每节课都附有 标签 。每当学生验证课程时,他们都会验证关联的 标签 。每个内容都标有与这些标签对应的先决条件。
在一个页面上,我想根据用户解锁的标签显示用户可以访问的所有歌曲。如果他们解锁了与歌曲关联的所有标签,则可以查看;否则他们不能。
这是一节课的模型(名为课程):
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)