用M2M关系直通表值过滤Django查询集

问题描述

我正在尝试这样做: queryset.filter(m2m_related_lookup__through_table_field=value)

以下是简化后的模型:

class User(models.Model):
    name = models.CharField("nom", max_length=100)
    surname = models.CharField("cognoms", max_length=100)

class Activity(models.Model):
    name = models.CharField("Títol", max_length=200)
    date_start = models.DateField("Dia inici")
    date_end = models.DateField("Dia finalització")
    enrolled = models.ManyToManyField(User, related_name='enrolled_activities', through='ActivityEnrolled')

class ActivityEnrolled(models.Model):
    class Meta:
        db_table = 'main_activity_personetes_enrolled'

    activity = models.ForeignKey(Activity, on_delete=models.CASCADE)
    user = models.ForeignKey(Personeta, on_delete=models.CASCADE)
    date_enrolled = models.DateTimeField("data d'inscripció")
    confirmed = models.BooleanField("confirmada", default=False)
我想很简单,只是一个带有自定义直通表的多2多个,这样我就可以在那里存储注册日期和其他一些东西。 此关系设置为Activity,Related_Name为‘Enabled_Actives’。

那么,如何使用Django的ORM查询"ActivityEnrolled.Enrollment_Date在2019年的所有用户"?

这是用于Django Admin中CHANGE_LIST视图的自定义过滤(带有admin.SimpleListFilter),它列出了用户项。换句话说,就像我在做User.objects.filter(Blabla)。

正在尝试:queryset.filter(enrolled_activities__date_enrolled__year=2019)显然会抛出错误Related Field Get Invalid Lookup:Date_Enabled,因为Enabled_Activity引用的不是直通表,而是相关表(即:Activity),并且该字段不存在。

唯一的解决方案是查询直通表而不是用户吗? LIKE:ActivityEnrolled.objects.filter(date_enrolled__year=2019)+对结果进行分组,以便为每个用户只返回一行。我知道我可以做到,但这很糟糕,我一直在试图找到一种更干净的方法来避免它,但没有成功。

非常感谢!!


解决方案

那么,如何使用Django的ORM查询ActivityEnrolled.enrollment_date在2019年的所有用户?

多对多关系实际上只是两个一对多表的组合。这样我们就可以过滤上的一对多关系了:

User.objects.filter(activityenrolled__enrollment_date__year=2019).distinct()

如果.distinct()用户在2019年注册了多个活动,则.distinct()将阻止生成同一用户。

相关文章