Django第二m2m关系

时间:2016-02-08 05:51:15

标签: python django django-models django-filter

我有两种型号:用户和主板。

class Board(models.Model):
    title = models.CharField(max_length=20, verbose_name=u'Название')
    members = models.ManyToManyField(to='user.User', related_name='boards', verbose_name=u'Участники')

我想获得一个用户ID列表,其中至少有一个与当前用户共用的板。如果我使用这个过滤器:

User.objects.filter(boards__members__id=self.request.user.id).values_list('id', flat=True)

它让我回头

  

[1,2,6,1,2,3]

我期待这个结果。但是当我使用:

self.request.user.boards.all().values_list('members__id', flat=True)

它返回一个列表,其中只包含当前用户ID。

  

[1,1]

会发生什么?

UPD

我忘记了一件重要的事情:有一个功能,看起来像:

def has_related_value(obj, field, channel_val):
    filter_by_val = channel_val
    property_name, filter_by_val = field.split('__', 1)

    attr = getattr(obj, property_name)
    if hasattr(attr, 'all'):
        return getattr(obj, property_name).filter(**{filter_by_val: channel_val}).exists()

大致称之为:has_related_value(self.request.user, 'boards__members__id', self.request.user.id)。也许,我可以将return getattr(obj, property_name).filter(**{filter_by_val: channel_val}).exists()更改为obj.__class__.objects.filter(pk=obj.pk, **{field: channel_val}).exists(),但我不想更改此功能。所以,我试图找到这样的“字段”和“channel_val”值,这将是有效的。 “channel_val”也必须是常量,因此“field” - “boards__in”和“channel_val” - self.connection.user.boards.all()不起作用。

2 个答案:

答案 0 :(得分:0)

这是正确的行为,因为self.request.user引用了当前用户,这就是您获取当前用户关系对象的原因。如果您需要整个User对象模型,则需要使用Django User Model来获得结果

答案 1 :(得分:0)

让我们稍微分解一下。首先,您想知道当前用户所属的电路板:

boards = Board.objects.filter(members=self.request.user)

然后,您想知道属于这些主板的所有用户ID(可能存在重复项,因此请使用distinct()):

User.objects.filter(
    boards__in=boards
).distinct().values_list('id', flat=True)

你可以将它们混合在一起:

User.objects.filter(
    boards__in=Board.objects.filter(members=self.request.user)
).distinct().values_list('id', flat=True)

现在,您唯一需要担心的是request.user.id可能在结果中。您可以使用exclude子句删除它:

User.objects.exclude(
    id=self.request.user.id
).filter(
    boards__in=Board.objects.filter(members=self.request.user)
).distinct().values_list('id', flat=True)