国产chinesehdxxxx野外,国产av无码专区亚洲av琪琪,播放男人添女人下边视频,成人国产精品一区二区免费看,chinese丰满人妻videos

Django drf Filtering

2020-01-22 11:45 更新

Filtering

“ 由Django Manager提供的根QuerySet描述了數(shù)據(jù)庫(kù)表中的所有對(duì)象??墒峭ǔD阈枰闹皇沁x擇完整對(duì)象中的一個(gè)子集而已。—— Django文檔 ”

REST framework列表視圖的默認(rèn)行為是返回一個(gè)model的全部queryset。通常你卻想要你的API來(lái)限制queryset返回的數(shù)據(jù)。

最簡(jiǎn)單的過(guò)濾任意GenericAPIView子視圖queryset的方法就是重寫(xiě)它的.get_queryset()方法。

重寫(xiě)這個(gè)方法允許你使用很多不同的方式來(lái)定制視圖返回的queryset。

Filtering against the current user(根據(jù)當(dāng)前用戶進(jìn)行過(guò)濾)

您可能想要過(guò)濾queryset,以確保只返回與發(fā)出請(qǐng)求的當(dāng)前已驗(yàn)證用戶相關(guān)的結(jié)果。

你可以通過(guò)基于request.user的值進(jìn)行過(guò)濾來(lái)實(shí)現(xiàn)。

比如:

from myapp.models import Purchase
from myapp.serializers import PurchaseSerializer
from rest_framework import generics

class PurchaseList(generics.ListAPIView):
    serializer_class = PurchaseSerializer

    def get_queryset(self):
        """
        This view should return a list of all the purchases
        for the currently authenticated user.
        """
        user = self.request.user
        return Purchase.objects.filter(purchaser=user)

Filtering against the URL(根據(jù)URL進(jìn)行過(guò)濾)

另一種過(guò)濾方式可能包括基于URL的某些部分來(lái)限制queryset。

例如,如果你的URL配置包含一個(gè)參數(shù)如下:

url('^purchases/(?P<username>.+)/$', PurchaseList.as_view()),

你就可以寫(xiě)一個(gè)view,返回基于URL中的username參數(shù)進(jìn)行過(guò)濾的結(jié)果。

class PurchaseList(generics.ListAPIView):
    serializer_class = PurchaseSerializer

    def get_queryset(self):
        """
        This view should return a list of all the purchases for
        the user as determined by the username portion of the URL.
        """
        username = self.kwargs['username']
        return Purchase.objects.filter(purchaser__username=username)

Filtering against query parameters(根據(jù)查詢(xún)參數(shù)進(jìn)行過(guò)濾)

過(guò)濾初始查詢(xún)集的最后一個(gè)示例是基于url中的查詢(xún)參數(shù)確定初始查詢(xún)集。

我們可以通過(guò)重寫(xiě).get_queryset()方法來(lái)處理像http://example.com/api/purchases?username=denvercoder9這樣的網(wǎng)址,并且只有在URL中包含username參數(shù)時(shí),才過(guò)濾queryset:

class PurchaseList(generics.ListAPIView):
    serializer_class = PurchaseSerializer

    def get_queryset(self):
        """
        Optionally restricts the returned purchases to a given user,
        by filtering against a `username` query parameter in the URL.
        """
        queryset = Purchase.objects.all()
        username = self.request.query_params.get('username', None)
        if username is not None:
            queryset = queryset.filter(purchaser__username=username)
        return queryset

Generic Filtering(通用過(guò)濾)

除了能夠重寫(xiě)默認(rèn)的queryset,REST框架還包括對(duì)通用過(guò)濾后端的支持,允許你輕松構(gòu)建復(fù)雜的檢索器和過(guò)濾器。

通用過(guò)濾器也可以在browsable API和admin API中顯示為HTML控件。

filter-controls.png

Setting filter backends(設(shè)置通用過(guò)濾后端)

默認(rèn)過(guò)濾器后端可以在全局設(shè)置中使用DEFAULT_FILTER_BACKENDS來(lái)配置。例如。

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}

你還可以使用基于GenericAPIView類(lèi)的視圖在每個(gè)view或每個(gè)viewset基礎(chǔ)上設(shè)置過(guò)濾器后端。

import django_filters.rest_framework
from django.contrib.auth.models import User
from myapp.serializers import UserSerializer
from rest_framework import generics

class UserListView(generics.ListAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)

Filtering and object lookups(過(guò)濾和對(duì)象查找)

請(qǐng)注意,如果為view配置過(guò)濾器后端,并且用于過(guò)濾list views,則它也將用于過(guò)濾用于返回單個(gè)對(duì)象的queryset。

例如,給定前面的示例以及一個(gè)ID為4675的產(chǎn)品,以下URL將返回相應(yīng)的對(duì)象或者返回404,具體取決于給定的產(chǎn)品實(shí)例是否滿足篩選條件。

http://example.com/api/products/4675/?category=clothing&max_price=10.00

Overriding the initial queryset(覆蓋初始queryset)

請(qǐng)注意,你可以同時(shí)重寫(xiě).get_queryset()方法或使用通用過(guò)濾,并且一切都會(huì)按照預(yù)期生效。 例如,如果Product與User(名為purchase)具有多對(duì)多關(guān)系,則可能需要編寫(xiě)如下所示的view:

class PurchasedProductsList(generics.ListAPIView):
    """
    Return a list of all the products that the authenticated
    user has ever purchased, with optional filtering.
    """
    model = Product
    serializer_class = ProductSerializer
    filter_class = ProductFilter

    def get_queryset(self):
        user = self.request.user
        return user.purchase_set.all()

API Guide

DjangoFilterBackend(Django過(guò)濾后端)

django-filter庫(kù)包含一個(gè)為REST framework提供高度可定制字段過(guò)濾的DjangoFilterBackend類(lèi)。

要使用DjangoFilterBackend,首先要先安裝django-filter。

pip install django-filter

現(xiàn)在,你需要將filter backend 添加到你django project的settings中:

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}

或者你也可以將filter backend添加到一個(gè)單獨(dú)的view或viewSet中:

from django_filters.rest_framework import DjangoFilterBackend

class UserListView(generics.ListAPIView):
    ...
    filter_backends = (DjangoFilterBackend,)

如果你正在使用 browsable API或 admin API,你還需要安裝django-crispy-forms,通過(guò)使用Bootstarp3渲染來(lái)提高filter form在瀏覽器中的展示效果。

pip install django-crispy-forms

安裝完成后,將crispy-forms添加到你Django project的INSTALLED_APPS中,browsable API將為DjangoFilterBackend提供一個(gè)像下面這樣的filter control:django filter

Specifying filter fields(指定篩選字段)

如果你的需求都是些簡(jiǎn)單相等類(lèi)型的篩選,那么你可以在你的view或viewSet里面設(shè)置一個(gè)filter_fields屬性,列出所有你想依靠篩選的字段集合。

class ProductList(generics.ListAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filter_fields = ('category', 'in_stock')

這將為你列出來(lái)的字段自動(dòng)創(chuàng)建一個(gè)filterSet,允許你想下面這樣請(qǐng)求篩選結(jié)果:

http://example.com/api/products?category=clothing&in_stock=True

Specifying a FilterSet(指定FilterSet)

對(duì)于更高級(jí)的過(guò)濾要求,你可以指定在view中應(yīng)該使用的FilterSet類(lèi)。例如:

import django_filters
from myapp.models import Product
from myapp.serializers import ProductSerializer
from rest_framework import generics

class ProductFilter(django_filters.rest_framework.FilterSet):
    min_price = django_filters.NumberFilter(name="price", lookup_expr='gte')
    max_price = django_filters.NumberFilter(name="price", lookup_expr='lte')
    class Meta:
        model = Product
        fields = ['category', 'in_stock', 'min_price', 'max_price']

class ProductList(generics.ListAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)
    filter_class = ProductFilter

這將允許你向下面一樣發(fā)出請(qǐng)求,如:

http://example.com/api/products?category=clothing&max_price=10.00

你也可以使用django-filter跨越關(guān)系,讓我們假設(shè)每個(gè)產(chǎn)品都有Manufacturer模型的外鍵,所以我們創(chuàng)建過(guò)濾器使用Manufacturer名稱(chēng)過(guò)濾。例如:

import django_filters
from myapp.models import Product
from myapp.serializers import ProductSerializer
from rest_framework import generics

class ProductFilter(django_filters.rest_framework.FilterSet):
    class Meta:
        model = Product
        fields = ['category', 'in_stock', 'manufacturer__name']

這使我們能夠進(jìn)行如下查詢(xún):

http://example.com/api/products?manufacturer__name=foo

這很好,但它將Django的雙下劃線約定作為API的一部分暴露出來(lái)。如果你想顯式地命名過(guò)濾器參數(shù),你可以顯式地將它包含在FilterSet類(lèi)中:

import django_filters
from myapp.models import Product
from myapp.serializers import ProductSerializer
from rest_framework import generics

class ProductFilter(django_filters.rest_framework.FilterSet):
    manufacturer = django_filters.CharFilter(name="manufacturer__name")

    class Meta:
        model = Product
        fields = ['category', 'in_stock', 'manufacturer']

現(xiàn)在你可以下面這樣執(zhí)行:

http://example.com/api/products?manufacturer=foo

有關(guān)使用過(guò)濾器集的更多詳細(xì)信息,請(qǐng)參閱django-filter文檔。

Hints & Tips(提示)

  • 默認(rèn)情況下未啟用過(guò)濾。如果你想使用DjangoFilterBackend記得確保它是通過(guò)使用DEFAULT_FILTER_BACKENDS設(shè)置安裝的。
  • 使用布爾字段時(shí),您應(yīng)該在網(wǎng)址查詢(xún)參數(shù)中使用True和False值,而不是0,1,true或false。 (允許的布爾值目前硬連線在Django的NullBooleanSelect實(shí)現(xiàn)中。)
  • django-filter支持使用Django的雙下劃線語(yǔ)法對(duì)關(guān)系進(jìn)行過(guò)濾。

SearchFilter(搜索過(guò)濾)

SearchFilter類(lèi)支持基于簡(jiǎn)單單查詢(xún)參數(shù)的搜索,并且基于Django admin的搜索功能。

在使用時(shí), browsable API將包括一個(gè)SearchFilter控件:search-filter.png

僅當(dāng)view中設(shè)置了search_fields屬性時(shí),才應(yīng)用SearchFilter類(lèi)。search_fields屬性應(yīng)該是model中文本類(lèi)型字段的名稱(chēng)列表,例如CharField或TextField。

class UserListView(generics.ListAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    filter_backends = (filters.SearchFilter,)
    search_fields = ('username', 'email')

這將允許客戶端通過(guò)進(jìn)行以下查詢(xún)來(lái)過(guò)濾列表中的項(xiàng)目:

http://example.com/api/users?search=russell

你還可以在查找API中使用雙下劃線符號(hào)對(duì)ForeignKey或ManyToManyField執(zhí)行相關(guān)查找:

search_fields = ('username', 'email', 'profile__profession')

默認(rèn)情況下,搜索將使用不區(qū)分大小寫(xiě)的部分匹配。 搜索參數(shù)可以包含多個(gè)搜索項(xiàng),其應(yīng)該是空格和/或逗號(hào)分隔。 如果使用多個(gè)搜索術(shù)語(yǔ),則僅當(dāng)所有提供的術(shù)語(yǔ)都匹配時(shí)才在列表中返回對(duì)象。

可以通過(guò)在search_fields前面添加各種字符來(lái)限制搜索行為。

  • '^' 以指定內(nèi)容開(kāi)始.
  • '=' 完全匹配
  • '@' 全文搜索(目前只支持Django的MySQL后端)
  • '$' 正則搜索

例如:

search_fields = ('=username', '=email')

默認(rèn)情況下,搜索參數(shù)名為'search',但這可以通過(guò)使用SEARCH_PARAM設(shè)置覆蓋。

有關(guān)更多詳細(xì)信息,請(qǐng)參閱Django文檔。

OrderingFilter(排序篩選)

OrderingFilter類(lèi)支持簡(jiǎn)單的查詢(xún)參數(shù)控制結(jié)果排序。ordering-filter.png

默認(rèn)情況下,查詢(xún)參數(shù)名為'ordering',但這可以通過(guò)使用ORDERING_PARAM設(shè)置覆蓋。

例如,按用戶名排序用戶:

http://example.com/api/users?ordering=username

客戶端還可以通過(guò)為字段名稱(chēng)加上'-'來(lái)指定反向排序,如下所示:

http://example.com/api/users?ordering=-username

還可以指定多個(gè)排序:

http://example.com/api/users?ordering=account,username

Specifying which fields may be ordered against(指定支持排序的字段)

建議你明確指定API應(yīng)在ordering filter中允許哪些字段。您可以通過(guò)在view中設(shè)置ordering_fields屬性來(lái)實(shí)現(xiàn)這一點(diǎn),如下所示:

class UserListView(generics.ListAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    filter_backends = (filters.OrderingFilter,)
    ordering_fields = ('username', 'email')

這有助于防止意外的數(shù)據(jù)泄漏,例如允許用戶針對(duì)密碼哈希字段或其他敏感數(shù)據(jù)進(jìn)行排序。

如果不在視圖上指定ordering_fields屬性,過(guò)濾器類(lèi)將默認(rèn)允許用戶對(duì)serializer_class屬性指定的serializer上的任何可讀字段進(jìn)行過(guò)濾。

如果你確信視圖正在使用的queryset不包含任何敏感數(shù)據(jù),則還可以通過(guò)使用特殊值'__all__'來(lái)明確指定view應(yīng)允許對(duì)任何model字段或queryset進(jìn)行排序。

class BookingsListView(generics.ListAPIView):
    queryset = Booking.objects.all()
    serializer_class = BookingSerializer
    filter_backends = (filters.OrderingFilter,)
    ordering_fields = '__all__'

Specifying a default ordering(指定默認(rèn)排序)

如果在view中設(shè)置了ordering屬性,則將把它用作默認(rèn)排序。

通常,你可以通過(guò)在初始queryset上設(shè)置order_by來(lái)控制此操作,但是使用view中的ordering參數(shù)允許你以某種方式指定排序,然后可以將其作為上下文自動(dòng)傳遞到呈現(xiàn)的模板。如果它們用于排序結(jié)果的話就能使自動(dòng)渲染不同的列標(biāo)題成為可能。

class UserListView(generics.ListAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    filter_backends = (filters.OrderingFilter,)
    ordering_fields = ('username', 'email')
    ordering = ('username',)

ordering屬性可以是字符串或字符串的列表/元組。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)