将 Django FilterSet 应用于带注释的查询集?
Applying a Django FilterSet to an Annotated QuerySet?
我正在尝试将过滤器应用于带注释的查询集,就像在此处完成的那样:
https://docs.djangoproject.com/en/2.0/topics/db/aggregation/#filtering-on-annotations
类似于下面的代码片段,我想将 highly_rated
片段设为一个 FilterSet 来获取请求参数
highly_rated = Count('books', filter=Q(books__rating__gte=7))
Author.objects.annotate(num_books=Count('books'), highly_rated_books=highly_rated)
我想使 highly_rated
部分成为一个筛选请求查询的 FilterSet。类似于:
class MainFilter(FilterSet):
class Meta:
model = Author
fields = {
author: ['in', 'exact'],
genre: ['in', 'exact']
}
class AnnotatedFilter(FilterSet):
class Meta:
fields = {
'books__rating': ['gt', 'lt' ],
}
class MyView(ListApiView):
filter_class = AuthorFilter
def get_queryset(self):
annotated_filter = AnnotatedFilter(request) # how do I set up another filter based on the request?
Author.objects.annotate(num_books=Count('books'), FilterSet=annotated_filter) # how do I apply it to an annotated queryset?
所有这样我就可以查询类似的东西:
api/authors/?genre=Fantasy&books__rating__gt=5
其中一个参数针对所有记录执行,而其他参数针对注释部分执行。
非常感谢任何帮助。谢谢!
将get_queryset()
方法更改为
def get_queryset(self):
return Author.objects.annotate(num_books=Count('books')
并将 Filter class
中的字段定义为
class AuthorFilter(FilterSet):
num_books = filters.NumberFilter(name='num_books')
class Meta:
model = Author
fields = ['num_books',]#other fields
然后使用 api 作为 /api/end/point/authorlist/?num_books=10
示例
models.py
from django.db import models
class Sample(models.Model):
foo = models.IntegerField()
bar = models.IntegerField()
views.py
from django.db.models import F
from django_filters import rest_framework as filters
class MySampleAPI(viewsets.ModelViewSet):
filter_backends = (filters.DjangoFilterBackend,)
filter_class = SampleFilterClass
serializer_class = SampleSerializerClass
def get_queryset(self):
return Sample.objects.annotate(foo_bar_sum=F('foo') + F('bar'))
filters.py
from django_filters import rest_framework as filters
class SampleFilterClass(filters.FilterSet):
sum = filters.NumberFilter(name='foo_bar_sum', lookup_expr='gte')
class Meta:
model = Sample
fields = ['sum', ]
JPG 的答案对我有用,但我不得不在过滤器中用标签替换名称 Class:
class AuthorFilter(FilterSet):
num_books = filters.NumberFilter(label='num_books') # here
class Meta:
model = Author
fields = ['num_books',]#other fields
我正在尝试将过滤器应用于带注释的查询集,就像在此处完成的那样: https://docs.djangoproject.com/en/2.0/topics/db/aggregation/#filtering-on-annotations
类似于下面的代码片段,我想将 highly_rated
片段设为一个 FilterSet 来获取请求参数
highly_rated = Count('books', filter=Q(books__rating__gte=7))
Author.objects.annotate(num_books=Count('books'), highly_rated_books=highly_rated)
我想使 highly_rated
部分成为一个筛选请求查询的 FilterSet。类似于:
class MainFilter(FilterSet):
class Meta:
model = Author
fields = {
author: ['in', 'exact'],
genre: ['in', 'exact']
}
class AnnotatedFilter(FilterSet):
class Meta:
fields = {
'books__rating': ['gt', 'lt' ],
}
class MyView(ListApiView):
filter_class = AuthorFilter
def get_queryset(self):
annotated_filter = AnnotatedFilter(request) # how do I set up another filter based on the request?
Author.objects.annotate(num_books=Count('books'), FilterSet=annotated_filter) # how do I apply it to an annotated queryset?
所有这样我就可以查询类似的东西:
api/authors/?genre=Fantasy&books__rating__gt=5
其中一个参数针对所有记录执行,而其他参数针对注释部分执行。
非常感谢任何帮助。谢谢!
将get_queryset()
方法更改为
def get_queryset(self):
return Author.objects.annotate(num_books=Count('books')
并将 Filter class
中的字段定义为
class AuthorFilter(FilterSet):
num_books = filters.NumberFilter(name='num_books')
class Meta:
model = Author
fields = ['num_books',]#other fields
然后使用 api 作为 /api/end/point/authorlist/?num_books=10
示例
models.py
from django.db import models
class Sample(models.Model):
foo = models.IntegerField()
bar = models.IntegerField()
views.py
from django.db.models import F
from django_filters import rest_framework as filters
class MySampleAPI(viewsets.ModelViewSet):
filter_backends = (filters.DjangoFilterBackend,)
filter_class = SampleFilterClass
serializer_class = SampleSerializerClass
def get_queryset(self):
return Sample.objects.annotate(foo_bar_sum=F('foo') + F('bar'))
filters.py
from django_filters import rest_framework as filters
class SampleFilterClass(filters.FilterSet):
sum = filters.NumberFilter(name='foo_bar_sum', lookup_expr='gte')
class Meta:
model = Sample
fields = ['sum', ]
JPG 的答案对我有用,但我不得不在过滤器中用标签替换名称 Class:
class AuthorFilter(FilterSet):
num_books = filters.NumberFilter(label='num_books') # here
class Meta:
model = Author
fields = ['num_books',]#other fields