Django REST framework-filtrage contre query param

J'ai donc créé mon "API" en utilisant REST framework, essayant maintenant de le filtrer. Voilà comment je m' models.py ressemblent plus ou moins:

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)

J'aimerais donc voir dans mon fichier JSON "tous les passagers dans un espace de travail particulier "ou" tous les passagers dans une compagnie aérienne particulière " etc.

Ici, c'est ma, 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

Et 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

c'est la première fois que J'utilise REST framework, j'ai vérifié les documents, ils m'ont aidé avec ce que j'ai fait jusqu'à présent, je voudrais utiliser

filtrage par rapport au paramètre de requête: http://www.django-rest-framework.org/api-guide/filtering/#filtering-against-query-parameters

vous ne Pouvez pas vraiment obtenir..

25
demandé sur f.cipriani 2014-01-17 13:50:35

3 réponses

donc avec les @ limelights j'ai réussi à faire ce que je voulais, voici le code:

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
41
répondu knowbody 2017-03-21 08:14:37

Vous pouvez obtenir la même fonctionnalité de la boîte juste en utilisant le paquet django-filter comme indiqué dans les docs 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')

dans ce cas, vous devrez faire le filtrage en utilisant 'workspace=1' ou 'workspace__airline=1'

6
répondu Gabriel Muj 2016-02-25 11:48:06

django app applique des filtres sur le queryset d'une vue en utilisant les paramètres de requête entrants d'une manière propre et élégante.

Qui peut être installé avec pip comme pip install drf-url-filters

Exemple D'Utilisation

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)
4
répondu Manjit Kumar 2016-04-09 21:37:50