如何根据传递的过滤器编写动态 django orm 查询集?
How to write a dynamic django orm queryset based on the filters passed?
我需要根据从前端作为 json 传递的过滤器在查询集上动态应用过滤器。
例如
如果 json 通过是:{ id:[1,2,3] }
那么查询集将是:Model.objects.filter(id__in=id)
如果 json 传递为:{ id:[1,2,3],country:['india','australia'] }
那么查询集将是:Model.objects.filter(id__in=id,country__in=country)
如何动态实现?
您可以使用 if/else 语句来检测国家/地区列表是否为空:
if not country:
Model.objects.filter(id__in=id)
else:
Model.objects.filter(id__in=id, country__in=country)
编辑:
评论指出过滤器的数量是动态的。所以在 Django 中 .filter()
returns 另一个 QuerySet
和 Querysets 被延迟评估,意味着 they can be chained 并在循环中使用。
所以使用unpacking(**
),我们可以组成kwargs
传递给.filter()
。
因为没有提供确切的 datatype/schema 过滤器,所以我将使用字典作为示例,filter_dictionary
。在这本词典中,key
是将要使用的过滤器,value
将是一个列表。
# Compose first Queryset
qs = Model.objects.all()
# Loop over dictionary
for key, value in filter_dictionary.items():
# Use unpacking to compose kwarg
qs.filter(**{'{0}__in'.format(key): value})
# do something with the QuerySet
只需使用一个 django_filters
from django_filters import rest_framework as filters
class ContentFilter(filters.FilterSet):
id = filters.NumberFilter(lookup_expr="in")
country = filters.CharFilter(lookup_expr="in")
class Meta:
model = <your_model>
fields = ['id', 'country']
然后添加到您的视图中class
filterset_class = ContentFilter
我需要根据从前端作为 json 传递的过滤器在查询集上动态应用过滤器。
例如
如果 json 通过是:{ id:[1,2,3] } 那么查询集将是:Model.objects.filter(id__in=id)
如果 json 传递为:{ id:[1,2,3],country:['india','australia'] }
那么查询集将是:Model.objects.filter(id__in=id,country__in=country)
如何动态实现?
您可以使用 if/else 语句来检测国家/地区列表是否为空:
if not country:
Model.objects.filter(id__in=id)
else:
Model.objects.filter(id__in=id, country__in=country)
编辑:
评论指出过滤器的数量是动态的。所以在 Django 中 .filter()
returns 另一个 QuerySet
和 Querysets 被延迟评估,意味着 they can be chained 并在循环中使用。
所以使用unpacking(**
),我们可以组成kwargs
传递给.filter()
。
因为没有提供确切的 datatype/schema 过滤器,所以我将使用字典作为示例,filter_dictionary
。在这本词典中,key
是将要使用的过滤器,value
将是一个列表。
# Compose first Queryset
qs = Model.objects.all()
# Loop over dictionary
for key, value in filter_dictionary.items():
# Use unpacking to compose kwarg
qs.filter(**{'{0}__in'.format(key): value})
# do something with the QuerySet
只需使用一个 django_filters
from django_filters import rest_framework as filters
class ContentFilter(filters.FilterSet):
id = filters.NumberFilter(lookup_expr="in")
country = filters.CharFilter(lookup_expr="in")
class Meta:
model = <your_model>
fields = ['id', 'country']
然后添加到您的视图中class
filterset_class = ContentFilter