有没有一种方法可以使用中间表中的字段来过滤Django中的多对多过滤器?

时间:2020-07-17 02:54:10

标签: python django django-orm

我在Django中有3个模型。

GroupMembershipUser

class Group(models.Model):
    name = models.CharField(max_length=32)
    permissions = JSONField(max_length=4096, default=list)

class Membership(models.Model):
    user = models.ForeignKey('User', on_delete=models.CASCADE, related_name='memberships')
    group = models.ForeignKey(Group, on_delete=models.CASCADE, related_name='memberships')
    expires_at = models.DateTimeField(null=True)
    valid = models.BooleanField(default=True)

class User(models.Model):
    groups = models.ManyToManyField(Group, through=Membership)
    last_seen = models.DateTimeField(null=True)
    created_at = models.DateTimeField(auto_now=True)

我想知道如何对用户进行“多对多”过滤,以仅从expires_at大于或为空的成员资格中检索组对象。谢谢!

1 个答案:

答案 0 :(得分:0)

我相信您正在寻找过期时间,但是我已经按照您的要求写了过期时间查询。

  1. 使用Q查询“ OR”。因此您的过滤器查询将是
from django.db.models import Q
Q(expires_at__gt=now) | Q(expires_at__isnull=True)
  1. 您要过滤特定用户的成员资格。因此,您的查询可以归结为
Membership.objects.filter(user=user).filter(Q(expires_at__gt=now) | Q(expires_at__isnull=True))
  1. 获取查询的所有组ID
Membership.objects.filter(user=user).filter(Q(expires_at__gt=now) | Q(expires_at__isnull=True)).values_list('group_id', flat=True)
  1. 获取所有相关组
queryset = Membership.objects.filter(user=user).filter(Q(expires_at__gt=now) | Q(expires_at__isnull=True)).values_list('group_id', flat=True)

result = Group.objects.filter(id__in=queryset)

尽管我认为第4步必须有更好的解决方案,但这也很好。

如果您只是在寻找组名,那就足够了

result = Membership.objects.filter(user=user).filter(Q(expires_at__gt=now) | Q(expires_at__isnull=True)).values_list('group__name', flat=True)
相关问题