Python 基于关系| Django筛选记录

Python 基于关系| Django筛选记录,python,django,Python,Django,我有以下型号: class PodcastPlatform(models.Model): name = models.CharField(max_length = 60) badge_path = models.FilePathField(path = settings.BADGES_DIR, unique = True) class Meta: ordering = ['name'] def __str__(self): re

我有以下型号:

class PodcastPlatform(models.Model):
    name = models.CharField(max_length = 60)
    badge_path = models.FilePathField(path = settings.BADGES_DIR, unique = True)

    class Meta:
        ordering = ['name']

    def __str__(self):
        return self.name

class Podcast(models.Model):
    name = models.CharField(max_length = 60)
    description = models.CharField(max_length = 400)
    created = models.DateTimeField(auto_now_add = True)
    updated = models.DateTimeField(auto_now = True)

    class Meta:
        ordering = ['-created', '-updated']

    def __str__(self):
        return self.name

class PodcastLink(models.Model):
    podcast_platform = models.ForeignKey(PodcastPlatform, on_delete = models.CASCADE)
    podcast = models.ForeignKey(Podcast, on_delete = models.CASCADE)
    url = models.URLField(max_length = 400, verbose_name = 'URL')

    class Meta:
        ordering = ['podcast_platform__name']
        unique_together = ['podcast_platform', 'podcast']

    def __str__(self):
        return self.podcast_platform.name

    def get_badge_url(self):
        return static(re.search('img/.{0,}', self.podcast_platform.badge_path).group())
我想过滤
Podcast
模型的实例,其中至少有一个链接或
PodcastLink
模型的相关实例。 为此,我做了以下工作:

Podcast.objects.filter(podcastlink__gte = 1)
返回以下查询集:

<QuerySet [<Podcast: Libero tenetur>, <Podcast: Libero tenetur>, <Podcast: Libero tenetur>, <Podcast: Assumenda iusto>, <Podcast: Assumenda iusto>, <Podcast: Assumenda iusto>, <Podcast: Assumenda iusto>, <Podcast: Explicabo>, <Podcast: Explicabo>, <Podcast: Explicabo>, <Podcast: Explicabo>, <Podcast: Explicabo>]>
为什么我会得到重复的例子?据我所知,这不应该发生。。。另外,这很奇怪…

您可以使用
distinct()
来获取唯一的实例。您可能还希望根据计数进行筛选:

Podcast.objects.filter(podcastlink__count__gte = 1).distinct()
您可以使用
distinct()
获取唯一实例。您可能还希望根据计数进行筛选:

Podcast.objects.filter(podcastlink__count__gte = 1).distinct()

我假设您在
podcastlink.podcast
上有
related\u name='podcastlink'
或一些自动设置它的逻辑,否则您的代码不应该工作

Podcast.objects.filter(podcastlink\uu gte=1)
。没有任何意义。
podcastlink
是一个关系而不是一个数字。我猜它是偶然在
podcastlink\uu gte=1
上工作的,但在
podcastlink\uu gte=2
上不起作用。要测试关系是否存在,您应该使用
podcastlink\uuu isnull=False

Podcast.objects.filter(podcastlink__isnull=False)
但是,此查询将连接
Podcast
PodcastLink
,并为每个组合返回一个条目。由于每个
Podcast
可以有许多
PodcastLink
,因此您可能会得到重复的
Podcast
。要避免这些重复,请使用'distinct()

另一种方法是实际计算每个播客的链接数:

from django.db.models import Count
Podcast.objects.annotate(nb_links=Count('podcastlink')).filter(nb_links__gte=1)
在这种情况下,您不需要使用
distinct()
,因为您将
PodcastLink
聚合为
Podcast
中的计数器。使用此方法,您现在还可以决定过滤
Podcast
中至少有2个链接,如果您需要:

Podcast.objects.annotate(nb_links=Count('podcastlink')).filter(nb_links__gte=2)

我假设您在
podcastlink.podcast
上有
related\u name='podcastlink'
或一些自动设置它的逻辑,否则您的代码不应该工作

Podcast.objects.filter(podcastlink\uu gte=1)
。没有任何意义。
podcastlink
是一个关系而不是一个数字。我猜它是偶然在
podcastlink\uu gte=1
上工作的,但在
podcastlink\uu gte=2
上不起作用。要测试关系是否存在,您应该使用
podcastlink\uuu isnull=False

Podcast.objects.filter(podcastlink__isnull=False)
但是,此查询将连接
Podcast
PodcastLink
,并为每个组合返回一个条目。由于每个
Podcast
可以有许多
PodcastLink
,因此您可能会得到重复的
Podcast
。要避免这些重复,请使用'distinct()

另一种方法是实际计算每个播客的链接数:

from django.db.models import Count
Podcast.objects.annotate(nb_links=Count('podcastlink')).filter(nb_links__gte=1)
在这种情况下,您不需要使用
distinct()
,因为您将
PodcastLink
聚合为
Podcast
中的计数器。使用此方法,您现在还可以决定过滤
Podcast
中至少有2个链接,如果您需要:

Podcast.objects.annotate(nb_links=Count('podcastlink')).filter(nb_links__gte=2)

您正在查询链接到podcastlink.id大于1的podcast链接的podcast。你什么都不算。。。多个项目是由反向关系查询造成的,该查询创建了一个内部联接(因为多个podcastlink可以引用同一个podcast,它们在计算联接中多次出现),您正在查询链接到podcastlink.id大于1的podcast链接的podcast。你什么都不算。。。多个项目是由反向关系查询造成的,该查询创建了一个内部联接(因为多个podcastlinks可以引用同一个podcast,它们在已评估的联接中出现多次),感谢您的响应,最重要的是感谢您的解释!感谢您的回复,最重要的是感谢您的解释!