在 Django ORM 中过滤 order_by 关系
filtering the order_by relationship in Django ORM
在下面,产品通过贡献者有很多作者,contributor.role_code
定义了对产品所做贡献的确切类型。是否可以使用 Django ORM 过滤下面 order_by() 方法引用的贡献者?例如。我只想订购 contributor.role_code in ['A01', 'B01']
.
贡献者的产品
Product.objects.filter(
product_type__name=choices.PRODUCT_BOOK
).order_by(
'contributor__writer__last_name' # filter which contributors it uses?
)
要过滤特定值,请先构建您的可接受值列表:
accepted_values = ['A01', 'B01']
然后过滤此列表中的值:
Product.objects.filter(
product_type__name=choices.PRODUCT_BOOK
).filter(
contributor__role_code__in=accepted_values
).order_by(
'contributor__writer__last_name'
)
您可以通过注释子查询执行此操作:
- 定义代表我们想要订购的东西的子查询
- 用子查询注释原始查询集
- 按注释排序。
contributors_for_ordering = Contributor.objects.filter( # 1
product=OuterRef('pk'),
role_code__in=['A01', 'B01'],
).values('writer__last_name')
queryset = Product.objects.filter(
product_type__name=choices.PRODUCT_BOOK
).annotate( # 2
writer_last_name=Subquery(contributors_for_ordering[:1]) # Slice [:1] to ensure a single result
).order_by( # 3
'writer_last_name'
)
但是请注意,这里有一个潜在的怪癖。如果产品的贡献者同时具有 'A01' 和 'B01',我们无法控制将使用哪个来进行订购——我们将首先获得数据库 returns 中的任何一个。您可以在 contributors_for_ordering
中添加一个 order_by
子句来处理这个问题。
在下面,产品通过贡献者有很多作者,contributor.role_code
定义了对产品所做贡献的确切类型。是否可以使用 Django ORM 过滤下面 order_by() 方法引用的贡献者?例如。我只想订购 contributor.role_code in ['A01', 'B01']
.
Product.objects.filter(
product_type__name=choices.PRODUCT_BOOK
).order_by(
'contributor__writer__last_name' # filter which contributors it uses?
)
要过滤特定值,请先构建您的可接受值列表:
accepted_values = ['A01', 'B01']
然后过滤此列表中的值:
Product.objects.filter(
product_type__name=choices.PRODUCT_BOOK
).filter(
contributor__role_code__in=accepted_values
).order_by(
'contributor__writer__last_name'
)
您可以通过注释子查询执行此操作:
- 定义代表我们想要订购的东西的子查询
- 用子查询注释原始查询集
- 按注释排序。
contributors_for_ordering = Contributor.objects.filter( # 1
product=OuterRef('pk'),
role_code__in=['A01', 'B01'],
).values('writer__last_name')
queryset = Product.objects.filter(
product_type__name=choices.PRODUCT_BOOK
).annotate( # 2
writer_last_name=Subquery(contributors_for_ordering[:1]) # Slice [:1] to ensure a single result
).order_by( # 3
'writer_last_name'
)
但是请注意,这里有一个潜在的怪癖。如果产品的贡献者同时具有 'A01' 和 'B01',我们无法控制将使用哪个来进行订购——我们将首先获得数据库 returns 中的任何一个。您可以在 contributors_for_ordering
中添加一个 order_by
子句来处理这个问题。