用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()
将阻止生成同一用户。
相关文章