我有一些丑陋的代码可以生成我想要的东西。它正在工作,但只是必要的,因为我想用
values_list
做的事情不起作用。
member_channels = Channel.objects.filter(Q(members=request.user) | Q(owner=request.user)).prefetch_related('members').prefetch_related('owner')
members_nested = list(map(lambda channel: channel.members.all(), member_channels))
members = list(dict.fromkeys(itertools.chain(*members_nested)))
owners = list(map(lambda channel: channel.owner, member_channels))
# this is all the user's who's comment's the request.user should be able to see.
valid_comment_users = list(dict.fromkeys(members + owners))
我想做的和应该做的是:
member_channels = Channel.objects.filter(Q(members=request.user) | Q(owner=request.user)).prefetch_related('members').prefetch_related('owner')
member_ids = member_channels.values_list('members', 'owner', flat=True)
valid_comment_users = AppUser.objects.filter(id__in=member_ids).distinct()
问题是,对于
values_list
,我没有得到members
中每个频道的所有members_channels
,它似乎只返回所有频道中相同的members
,或者可能只是第一个会员我说不准。对为什么 values_list
对此不起作用有任何见解吗?
以下是模型及其关系:
class Channel(models.Model):
owner = models.ForeignKey(AppUser, on_delete=models.CASCADE)
members = models.ManyToManyField(AppUser, blank=True, related_name="members")
class Comment(models.Model):
owner = models.ForeignKey(AppUser, on_delete=models.CASCADE)
episode = models.ForeignKey(Episode, on_delete=models.CASCADE)
class Episode(models.Model):
owner = models.ForeignKey(AppUser, on_delete=models.CASCADE)
channels = models.ManyToManyField(Channel, blank=True)
AppUser
只是从Django auth扩展的用户模型。
flat=True
中的
values_list
只能与一个字段一起使用:
所以只需删除 flat=true 并在 python 中从中创建一个平面列表
https://docs.djangoproject.com/en/4.1/ref/models/querysets/#values-list
也许这样的东西更适合你:
member_channels = Channel.objects.filter(Q(members=request.user) | Q(owner=request.user)).values_list("id", flat=True)
AppUser.objects.filter(Q(members__channel__in=members_channel) | Q(owner__channel__in=members_channel))
倒退,你只需要知道
related_query_name
。由于您在 AppUser
和 Channel
之间有 2 个关系,我认为您必须在 related_query_name
或只是 related_name
中明确设置它。原来如此.filter({related_query_name}__channel__in=...)
https://docs.djangoproject.com/en/4.1/ref/models/fields/#django.db.models.ForeignKey.related_query_name
当使用
flat=True
时,values_list
返回一个简单的值列表而不是元组列表。
要在单个
members
调用中同时检索 owner
和 values_list
字段,您应该将其用作:
member_ids = member_channels.values_list('members__id', 'owner__id')
试试这个:
member_channels = Channel.objects.filter(Q(members=request.user) | Q(owner=request.user))
member_ids = member_channels.values_list('members__id', flat=True)
owner_ids = member_channels.values_list('owner__id', flat=True)
valid_comment_users = AppUser.objects.filter(Q(id__in=member_ids) | Q(id__in=owner_ids))