Let*_*zee 6 django django-views django-filter django-rest-framework
我有一个使用OrderingFilter后端的模型.现在只id允许按字段排序.
我想提供其他字段的排序选项,但不必在我的数据库中公开字段名称.有没有办法做到这一点?
pip install django-filter
Run Code Online (Sandbox Code Playgroud)
在你看来:
from rest_framework import viewsets, filters
from django_filters.filters import OrderingFilter
from .models import MyList
from .serializers import MyListSerializer
class MyFilter(django_filters.FilterSet):
surname = django_filters.CharFilter(name="model_field_name_2")
order_by_field = 'ordering'
ordering = OrderingFilter(
# fields(('model field name', 'parameter name'),)
fields=(
('model_field_name_1', 'name'),
('model_field_name_2', 'surname'),
('model_field_name_3', 'email'),
)
)
class Meta:
model = MyList
fields = ['model_field_name_2',]
class MyListViewSet(viewsets.ModelViewSet):
serializer_class = MyListSerializer
filter_backends = (filters.DjangoFilterBackend,)
filter_class = MyFilter
def get_queryset(self):
return MyList.objects.all()
Run Code Online (Sandbox Code Playgroud)
你可以做这样的事情:
/my-list?ordering=name,surname,email
/my-list?ordering=-email&surname=taylor
Run Code Online (Sandbox Code Playgroud)
django-filter docs:http: //django-filter.readthedocs.io/en/develop/ref/filters.html#orderingfilter
drf docs:http: //www.django-rest-framework.org/api-guide/filtering/#djangofilterbackend
我创建了一个AliasedOrderingFilter,可以很好地满足此需求。它扩展了ordering_fields属性,以允许用于字段和字符串的元组。例如,您可以将视图ordering_fields设置为:
ordering_fields = (('alias1', 'field1'),('alias2', 'field2'), 'field3')
Run Code Online (Sandbox Code Playgroud)
在与的请求中使用此类ordering=alias1,-alias2,field3将导致:
qs.order_by('field1', '-field2', 'field3)
Run Code Online (Sandbox Code Playgroud)
班级:
class AliasedOrderingFilter(OrderingFilter):
''' this allows us to "alias" fields on our model to ensure consistency at the API level
We do so by allowing the ordering_fields attribute to accept a list of tuples.
You can mix and match, i.e.:
ordering_fields = (('alias1', 'field1'), 'field2', ('alias2', 'field2')) '''
def remove_invalid_fields(self, queryset, fields, view):
valid_fields = getattr(view, 'ordering_fields', self.ordering_fields)
if valid_fields is None or valid_fields == '__all__':
return super(AliasedOrderingFilter, self).remove_invalid_fields(queryset, fields, view)
aliased_fields = {}
for field in valid_fields:
if isinstance(field, basestring):
aliased_fields[field] = field
else:
aliased_fields[field[0]] = field[1]
ordering = []
for raw_field in fields:
invert = raw_field[0] == '-'
field = raw_field.lstrip('-')
if field in aliased_fields:
if invert:
ordering.append('-{}'.format(aliased_fields[field]))
else:
ordering.append(aliased_fields[field])
return ordering
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2703 次 |
| 最近记录: |