网址查询中的Django自定义排序

时间:2018-12-18 14:30:14

标签: django api url django-rest-framework filtering

更新两个

很不幸,@ Reza Torkaman Ahmadi的想法最终没有实现。这是因为我们的程序具有依赖于get_queryset的筛选功能,并且在我们的视图中覆盖get_queryset方法会弄乱该功能。

所以,我和我的伴侣讨论了这个,这就是他的想法。

class OrderbyFilter(filters.OrderingFilter): def get_ordering(self, request, queryset, view): """ Ordering is set by a comma delimited ?$orderby=... query parameter. Extends the OrderingFilter of the django rest framework to redefine ordering parameters to "asc" and "desc". """ params = request.query_params.get(self.ordering_param) if params: field_queries = [param.strip() for param in params.split(',')] fields = [] for field_query in field_queries: field_query = field_query.split() if len(field_query) <= 2: while "asc" in field_query: field_query.remove("asc") for i, field in enumerate(field_query): if field == "desc": field_query[i-1] = "-" + field_query[i-1] while "desc" in field_query: field_query.remove("desc") fields.append(field_query[0]) else: fields.append([param.strip() for param in params.split(',')]) ordering = self.remove_invalid_fields(queryset, fields, view, request) if ordering: return ordering return self.get_default_ordering(view)

基本上,此函数将覆盖Django REST的源代码,尤其是OrderingFilter中的get_ordering函数。它的作用是,如果在字段后的查询中出现“ asc”,它将删除它,并将其视为正常(用于正常升序)

否则,如果存在'desc',则会删除'desc',并应用连字符。

更新已回答。应用了@Reza Torkaman Ahmadi的想法,并对其进行了修改以满足我的需求,效果很好。谢谢队友!

当前,在Django API rest框架中,如果用户希望按升序或降序查看列表,则必须执行以下操作:

“ Datastream&order_by = -name”以降序显示名称 “ Datastream&order_by = name”以升序显示名称。

我想进行一个自定义查询,在其中键入“ Datastream&order_by = asc名称”将按升序对名称进行排序,而“ desc名称”将按降序进行。

我已经看过REST框架的一些源代码,但是我看错了地方。被我应该做的事情困扰。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

您可以按照自己的方式进行操作。像这样:

class DatastreamViewSet(ModelViewSet):

    def get_queryset(self):
        queryset = super(DatastreamViewSet, self).get_queryset()

        order_by = self.request.query_params.get('order_by', '')
        if order_by:
            order_by_name = order_by.split(' ')[1]
            order_by_sign = order_by.split(' ')[0]
            order_by_sign = '' if order_by_sign == 'asc' else '-'
            queryset = queryset.order_by(order_by_sign + order_by_name)

        return queryset

这将查找查询参数order_by(如果提供),然后将其按空格分割,第一个将指示在order_by过滤器上使用+或-号,第二个将作为其名称。因此,将它们放在一起并创建文本,然后将其传递给order_by,这很有意义。

例如:

?order_by=asc name

在django中将是这样=>

return queryset.order_by('name')

答案 1 :(得分:0)

Django Rest Framework 的标准方式:

from rest_framework.filters import OrderingFilter

然后在您的 APIView 或 ViewSet 上

filter_backends = (OrderingFilter)
ordering_fields = ['field_name']

查询参数为 ordering 并且也支持反向排序。

GET https://example.com/?ordering=-field_name