DRF-在过滤器中,使用字段值代替默认的pk / id

时间:2019-04-27 11:57:58

标签: django-rest-framework query-parameters

我正在尝试使用DRF的过滤器,以便URL查询如下:

/roadname/?road=M5

不喜欢

/roadinfo/?road=1

当我有一个ForeignKey关系时,我似乎做不到。

我尝试使用没有运气的lookup_field(尽管不确定如何将其用于多个过滤器字段-我认为这不是答案)。我已经尝试过在视图中使用get_queryset()方法,如documentation中的第二个示例所示。我碰到的评论暗示这是不好的RESTApi做法-是吗?用户如何知道在前端客户端中键入“ 1”以获得“ M5”的结果?

我已经建立了两个非常简单的模型(以及序列化器,视图等),如下所示进行尝试。

如果我使用RoadName,则必须在过滤器搜索框中键入名称(而不是使用下拉菜单),但是url查询就是我想要的方式。

如果我使用RoadInfo(RoadInfo带有一个ForeignField到RoadName),则会在过滤器框中出现一个下拉列表,但是url查询使用ForeignKey pk。

我的问题:如何设置它,以便在使用RoadInfo时查询使用字段值而不是id / pk?

模型

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 个答案:

答案 0 :(得分:3)

road模型的RoadName属性上的数据 M5 。可以通过road__road RoadInfo 模型中进行过滤。

因此,请尝试 /roadname/?road__road=M5

相关问题