DRF - в фильтре используйте значение поля вместо pk / id по умолчанию - PullRequest
1 голос
/ 27 апреля 2019

Я пытаюсь использовать фильтры DRF, чтобы запрос URL был примерно таким:

/roadname/?road=M5

не так, как надо

/roadinfo/?road=1

Я не могу сделать это, когдаУ меня есть отношение ForeignKey.

Я попытался использовать lookup_field безуспешно (хотя в любом случае не уверен, как это будет работать для нескольких полей фильтра - я не думаю, что это ответ).Я попытался использовать метод get_queryset () в представлениях, как во втором примере в документации .Комментарий, с которым я столкнулся, предположил, что это плохая практика RESTApi - не так ли?Как пользователь узнает, что нужно ввести «1», чтобы получить результаты для «M5» во внешнем клиенте?

Я настроил две действительно простые модели (и сериализаторы, представления и т. Д.), Чтобыпопробуйте это, как показано ниже.

Если я использую RoadName, мне нужно ввести имя в поле поиска фильтра (а не выпадающий список), но URL-запрос - это то, что мне нужно.

Если я использую RoadInfo (у которого есть ForeignField to RoadName), я получаю выпадающий список в окне фильтра, но в URL-запросе используется ForeignKey pk.

Мой вопрос: как его настроить, чтобыкогда я использую RoadInfo, в запросе используется значение поля, а не id / pk?

Models

from django.db import models

class RoadName(models.Model):
    road = models.CharField(max_length=50)
    def __str__(self):
        return str(self.road)

class RoadInfo(models.Model):
    road = models.ForeignKey(RoadName, on_delete='CASCADE')
    # other data
    def __str__(self):
        return str(self.road)

Сериализаторы

from traffic.models import *
from rest_framework import serializers

class RoadNameSerializer(serializers.ModelSerializer):
    road = serializers.CharField()

    class Meta:
        model = RoadName
        exclude = ('id',)


class RoadInfoSerializer(serializers.ModelSerializer):
    road = RoadNameSerializer()

    class Meta:
        model = RoadInfo
        exclude = ('id',)

Просмотров

from traffic.serializers import *
from traffic.models import *
from django_filters import rest_framework as filters
from rest_framework import viewsets


class RoadNameViewSet(viewsets.ReadOnlyModelViewSet):
    """ List of all traffic count Counts """
    queryset = RoadName.objects.all()
    serializer_class = RoadNameSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filterset_fields = '__all__'

class RoadInfoViewSet(viewsets.ReadOnlyModelViewSet):
    """ List of all traffic count Counts """
    queryset = RoadInfo.objects.all()
    serializer_class = RoadInfoSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filterset_fields = '__all__'

1 Ответ

3 голосов
/ 27 апреля 2019

Данные M5 по атрибуту road модели RoadName.Его можно отфильтровать по road__road из RoadInfo модели.

Итак, попробуйте /roadname/?road__road=M5

...