如何从RegistrationCompletedByUser获取符合过滤条件的Registration查询集?
实现思路与解决方案
直接从Registration模型反向过滤
利用两个模型的一对多关联关系,直接通过Registration的反向关联字段跨表过滤,一步得到目标查询集:
completed_registrations = Registration.objects.filter( registrationcompletedbyuser__user=request.user, id__in=some_value, registrationcompletedbyuser__is_completed=True ).distinct()
- 用
registrationcompletedbyuser__前缀关联中间表字段,实现跨表条件过滤 - 加
distinct()是避免一个Registration对应多条符合条件的中间表记录时,查询集出现重复实例
先筛选中间表再关联查询
先找出符合条件的RegistrationCompletedByUser记录,再提取对应的Registration:
# 第一步:过滤中间表得到有效关联记录 valid_completed_entries = RegistrationCompletedByUser.objects.filter( user=request.user, registration__in=some_value, is_completed=True ) # 第二步:通过关联ID获取Registration查询集 completed_registrations = Registration.objects.filter( id__in=valid_completed_entries.values_list('registration_id', flat=True) )
values_list('registration_id', flat=True)返回纯ID列表,用该列表过滤Registration表,逻辑更直观
为什么prefetch_related没生效?
prefetch_related的作用是预加载关联数据,而非过滤主模型。它只会提前拉取关联的中间表数据,但不会剔除不符合条件的Registration。如果要在预加载时过滤关联数据,需配合Prefetch对象,但这仍不会过滤主模型:
from django.db.models import Prefetch filtered_completed = RegistrationCompletedByUser.objects.filter( user=request.user, is_completed=True ) # 这里得到的是所有id在some_value里的Registration,仅预加载了符合条件的关联数据 registrations = Registration.objects.filter(id__in=some_value).prefetch_related( Prefetch('registrationcompletedbyuser_set', queryset=filtered_completed) )
若只想保留有符合条件关联的Registration,仍需使用前两种方法。
模型管理器传递自定义参数的正确方式
自定义管理器时,直接给方法添加参数即可:
# 在models.py中修改Registration模型 from django.db import models from django.contrib.auth.models import User class RegistrationManager(models.Manager): def get_completed_by_user(self, user, allowed_registrations): return self.filter( registrationcompletedbyuser__user=user, id__in=allowed_registrations, registrationcompletedbyuser__is_completed=True ).distinct() class Registration(models.Model): name = models.CharField(max_length=255) number = models.SmallIntegerField(null=True, blank=True) objects = RegistrationManager() # 使用时调用方法传递参数 completed_registrations = Registration.objects.get_completed_by_user(request.user, some_value)
内容的提问来源于stack exchange,提问作者shraysalvi
相关产品推荐
相关产品推荐

