从具有一个不同字段的向后外键关系中获取 Django 查询集
Getting a django queryset from a backward foreign key relationship with one distinct field
使用 Django 1.8
我正在尝试通过向后外键关系获取查询集,其中源模型中的一个字段只有一个不同的值。
class Franchise(models.Model):
...
class Title(models.Model):
franchise = models.ForeignKey(Franchise, related_name='titles')
genre = models.CharField(max_length=20)
...
所以在这个例子中,我想获得一个 Franchise 对象的查询集,其中的所有 Titles 都具有相同的流派。我可以向 Franchise 模型添加方法并生成特许经营 ID 的列表以获得查询集,但这非常慢。
class Franchise(models.Model):
...
def get_title_genres(self):
self.titles.values_list('genre', flat=True).distinct()
def is_single_genre(self):
return len(self.get_title_genres()) == 1
franchise_ids = [
franchise.id
for franchise in Franchise.objects.all()
if franchise.is_single_genre()
]
queryset = Franchise.objects.filter(id__in=franchise_ids)
有没有更有效的方法可以做到这一点?
除非你需要一个查询集,否则你不需要第二个查询集id__in=franchise_ids
。
franchises = [
franchise for franchise in Franchise.objects.all()
if franchise.is_single_genre()
]
您可以使用 prefetch_related
通过查询集获取所有相关标题,但是您将无法重复使用 get_title_genres
方法,因为 values_list(...).distinct()
会触发一个新的 SQL 查询。
franchises = [
franchise for franchise in Franchise.objects.prefetch_related('titles')
if len(set(t.genre for t in franchise.titles)) == 1
]
使用 Django 1.8
我正在尝试通过向后外键关系获取查询集,其中源模型中的一个字段只有一个不同的值。
class Franchise(models.Model):
...
class Title(models.Model):
franchise = models.ForeignKey(Franchise, related_name='titles')
genre = models.CharField(max_length=20)
...
所以在这个例子中,我想获得一个 Franchise 对象的查询集,其中的所有 Titles 都具有相同的流派。我可以向 Franchise 模型添加方法并生成特许经营 ID 的列表以获得查询集,但这非常慢。
class Franchise(models.Model):
...
def get_title_genres(self):
self.titles.values_list('genre', flat=True).distinct()
def is_single_genre(self):
return len(self.get_title_genres()) == 1
franchise_ids = [
franchise.id
for franchise in Franchise.objects.all()
if franchise.is_single_genre()
]
queryset = Franchise.objects.filter(id__in=franchise_ids)
有没有更有效的方法可以做到这一点?
除非你需要一个查询集,否则你不需要第二个查询集id__in=franchise_ids
。
franchises = [
franchise for franchise in Franchise.objects.all()
if franchise.is_single_genre()
]
您可以使用 prefetch_related
通过查询集获取所有相关标题,但是您将无法重复使用 get_title_genres
方法,因为 values_list(...).distinct()
会触发一个新的 SQL 查询。
franchises = [
franchise for franchise in Franchise.objects.prefetch_related('titles')
if len(set(t.genre for t in franchise.titles)) == 1
]