簡體   English   中英

如何在 Django 中使用查詢字符串過濾查詢集?

[英]How to use Query Strings for filtering Querysets in Django?

我使用 REST 框架創建了我的“API”,現在我正在嘗試對其進行過濾。

這是我的models.py的樣子:

class Airline(models.Model):
    name = models.TextField()

class Workspace(models.Model):
    airline = models.ForeignKey(Airline)
    name = models.CharField(max_length=100)

class Passenger(models.Model):
    workspace = models.ForeignKey(Workspace)
    title = models.CharField(max_length=200)

我想在我的 JSON 文件中看到“特定工作區的所有乘客”或“特定航空公司的所有乘客”等。

這是我的serializers.py

class AirlineSerializer(serializers.ModelSerializer):
    class Meta:
        model = Airline


class WorkspaceSerializer(serializers.ModelSerializer):
    class Meta:
        model = Workspace


class PassengerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Passenger

views.py

class AirlineList(generics.ListCreateAPIView):
    model = Airline
    serializer_class = AirlineSerializer


class AirlineDetail(generics.RetrieveUpdateDestroyAPIView):
    model = Airline
    serializer_class = AirlineSerializer


class WorkspaceList(generics.ListCreateAPIView):
    model = Workspace
    serializer_class = WorkspaceSerializer


class WorkspaceDetail(generics.RetrieveUpdateDestroyAPIView):
    model = Workspace
    serializer_class = WorkspaceSerializer


class PassengerList(generics.ListCreateAPIView):
    model = Passenger
    serializer_class = PassengerSerializer


class PassengerDetail(generics.RetrieveUpdateDestroyAPIView):
    model = Passenger
    serializer_class = PassengerSerializer

我想對查詢參數使用過濾,但我真的不能得到它......

所以使用@limelights我設法做我想要的,這里是代碼:

class PassengerList(generics.ListCreateAPIView):
    model = Passenger
    serializer_class = PassengerSerializer

    # Show all of the PASSENGERS in particular WORKSPACE
    # or all of the PASSENGERS in particular AIRLINE
    def get_queryset(self):
        queryset = Passenger.objects.all()
        workspace = self.request.query_params.get('workspace')
        airline = self.request.query_params.get('airline')

        if workspace:
            queryset = queryset.filter(workspace_id=workspace)
        elif airline:
            queryset = queryset.filter(workspace__airline_id=airline)

        return queryset

您可以使用django-filter軟件包開箱即可獲得相同的功能,如文檔http://www.django-rest-framework.org/api-guide/filtering/#djangofilterbackend中所述

from rest_framework import filters 

class PassengerList(generics.ListCreateAPIView):
    model = Passenger
    serializer_class = PassengerSerializer
    queryset = Passenger.objects.all()
    filter_backends = (filters.DjangoFilterBackend,)
    filter_fields = ('workspace', 'workspace__airline')

在這種情況下,您必須使用'workspace = 1'或'workspace__airline = 1'進行過濾

這個django應用程序使用傳入的查詢參數以干凈和優雅的方式在視圖的查詢集上應用過濾器。

可以使用pip install drf-url-filters

用法示例

validations.py

from filters.schema import base_query_param_schema
from filters.validations import (
    CSVofIntegers,
    IntegerLike,
    DatetimeWithTZ
)

# make a validation schema for players filter query params
players_query_schema = base_query_param_schema.extend(
    {
        "id": IntegerLike(),
        "name": unicode,
        "team_id": CSVofIntegers(),  # /?team_id=1,2,3
        "install_ts": DatetimeWithTZ(),
        "update_ts": DatetimeWithTZ(),
    }
)

views.py

from rest_framework import (
    viewsets,
    filters,
)

from .models import Player, Team
from .serializers import PlayerSerializer, TeamSerializer
from .pagination import ResultSetPagination
from .validations import teams_query_schema, players_query_schema
from filters.mixins import (
    FiltersMixin,
)


class PlayersViewSet(FiltersMixin, viewsets.ModelViewSet):
    """
    This viewset automatically provides `list`, `create`, `retrieve`,
    `update` and `destroy` actions.
    """
    serializer_class = PlayerSerializer
    pagination_class = ResultSetPagination
    filter_backends = (filters.OrderingFilter,)
    ordering_fields = ('id', 'name', 'update_ts')
    ordering = ('id',)

    # add a mapping of query_params to db_columns(queries)
    filter_mappings = {
        'id': 'id',
        'name': 'name__icontains',
        'team_id': 'teams',   # many-to-many relationship
        'install_ts': 'install_ts',
        'update_ts': 'update_ts',
        'update_ts__gte': 'update_ts__gte',
        'update_ts__lte': 'update_ts__lte',
    }

    # add validation on filters
    filter_validation_schema = players_query_schema

    def get_queryset(self):
        """
        Optionally restricts the queryset by filtering against
        query parameters in the URL.
        """
        query_params = self.request.query_params
        queryset = Player.objects.prefetch_related(
            'teams'  # use prefetch_related to minimize db hits.
        ).all()

        # This dict will hold filter kwargs to pass in to Django ORM calls.
        db_filters = {}

        # update filters dict with incoming query params and then pass as
        # **kwargs to queryset.filter()
         db_filters.update(
            self.get_queryset_filters(
                query_params
            )
        )
        return queryset.filter(**db_filters)

您可以在 Django 中使用查詢字符串來過濾查詢集。您可以使用傳入的查詢參數對視圖的查詢集應用過濾器。

以下是如何過濾查詢集的示例:

class PassengerList(generics.ListCreateAPIView):
    model = Passenger
    serializer_class = PassengerSerializer

    def get_queryset(self):
        queryset = Passenger.objects.all()
        workspace_id = self.request.query_params.get('workspace_id', None)
        airline_id = self.request.query_params.get('airline_id', None)
        if workspace_id is not None:
            queryset = queryset.filter(workspace_id=workspace_id)
        if airline_id is not None:
            queryset = queryset.filter(workspace__airline_id=airline_id)
        return queryset

在此示例中,您可以按 workspace_id 和 airline_id 過濾查詢集。 如果 workspace_id 不是 None,則它按 workspace_id 過濾查詢集。 如果 airline_id 不是 None,則它按 workspace__airline_id3 過濾查詢集。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM