[英]Django second m2m relation
I have two models: User and Board. 我有两个模型:用户和委员会。
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'Участники')
And I want to get a list of users ids, which have at least one common board with current user. 我想获得一个用户ID列表,该ID与当前用户至少有一个共同的董事会。 If I use this filter: 如果我使用此过滤器:
User.objects.filter(boards__members__id=self.request.user.id).values_list('id', flat=True)
It returns me 它返回我
[1, 2, 6, 1, 2, 3] [1、2、6、1、2、3]
And I expect this result. 我期待这个结果。 But when I use: 但是当我使用时:
self.request.user.boards.all().values_list('members__id', flat=True)
It returns me a list, which contains only current user id. 它返回一个列表,其中仅包含当前用户ID。
[1, 1] [1,1]
What happens? 怎么了?
I forgot one important thing: there is a function, which look like: 我忘记了一件重要的事情:这里有一个函数,看起来像:
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()
And it is roughly called such: has_related_value(self.request.user, 'boards__members__id', self.request.user.id)
. 大致称为: has_related_value(self.request.user, 'boards__members__id', self.request.user.id)
。 Perhaps, I can change return getattr(obj, property_name).filter(**{filter_by_val: channel_val}).exists()
to obj.__class__.objects.filter(pk=obj.pk, **{field: channel_val}).exists()
, but i don't want to change this function. 也许,我可以将return getattr(obj, property_name).filter(**{filter_by_val: channel_val}).exists()
更改为obj.__class__.objects.filter(pk=obj.pk, **{field: channel_val}).exists()
,但我不想更改此功能。 So, i try to find such "field" and "channel_val" values, that will be work. 因此,我尝试找到这样的“字段”和“ channel_val”值,这将是可行的。 Also "channel_val" must be constant, so "field" - "boards__in" and "channel_val" - self.connection.user.boards.all() does not work. 同样,“ channel_val”必须恒定,因此“ field”-“ boards__in”和“ channel_val”-self.connection.user.boards.all()不起作用。
It's the correct behavior because self.request.user
refers to current user and that is why you are getting current user relationship objects. 这是正确的行为,因为self.request.user
指向当前用户,这就是为什么要获取当前用户关系对象的原因。 If you want entire User object model you need to use Django User Model to get results 如果您想要整个User对象模型,则需要使用Django User Model来获取结果
Let's break this down a bit. 让我们分解一下。 First, you want to know what boards the current user belongs to: 首先,您想知道当前用户属于哪个委员会:
boards = Board.objects.filter(members=self.request.user)
Then, you want to know all user ids that belong to those boards (there may be duplicates, so use distinct()
): 然后,您想知道所有属于这些板的用户ID(可能有重复的用户,所以请使用distinct()
):
User.objects.filter(
boards__in=boards
).distinct().values_list('id', flat=True)
You could mix those together: 您可以将它们混合在一起:
User.objects.filter(
boards__in=Board.objects.filter(members=self.request.user)
).distinct().values_list('id', flat=True)
Now, the only thing you need to worry about is that request.user.id
may be in the results. 现在,您唯一需要担心的是结果中可能存在request.user.id
。 You could remove that using an exclude
clause: 您可以使用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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.