Django api休息过滤manytomany

时间:2015-09-17 17:28:11

标签: python django rest django-rest-framework

我是Django和Django Api Rest FrameWork的新手

我正在尝试使用与ManyToMany关系

关联的两个模型开发Api

models.py

class Category(models.Model):
    name = models.CharField(max_length=100)

class Apartment(models.Model):
    id_2 = models.IntegerField(default= None)
    neighborhood = models.CharField(max_length=100)
    name = models.CharField(max_length=120)
    district = models.CharField(max_length=120)
    created = models.DateTimeField()
    cats = models.ManyToManyField(Category)
    address = models.CharField(max_length=200)
    postal_code = models.IntegerField()
    latitude = models.FloatField()
    longitude = models.FloatField()

serializers.py

class CategorySerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Category
        fields = ( 'id', 'name')

class AptSerializer(serializers.HyperlinkedModelSerializer):

    cats = CategorySerializer(many=True, read_only=True)

    class Meta:
        model = Apartment
        fields = ('id_2', 'neighborhood', 'name','district','created','cats','address','postal_code','latitude','longitude')

view.py

class AptViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows groups to be viewed or edited.
    """
    queryset = Apartment.objects.all()
    serializer_class = AptSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filter_fields = ('id_2', 'neighborhood', 'name', 'district','created','cats','address','postal_code','latitude','longitude')

routers.py

router.register(r'apartments', views.AptViewSet)

正如你所看到它实现了 DjangoFilterBackend 所以现在我可以使用urls类型进行过滤

http://localhost:8000/apartments/?district=Eixample

我得到了这个

 {
    "id_2": 1044121532,
    "neighborhood": "la Nova Esquerra de l'Eixample",
    "name": "Hotel Exe AB Viladomat",
    "district": "Eixample",
    "created": "2001-02-13T00:00:00Z",
    "cats": [
        {
            "id": 1073,
            "name": "Allotjament"
        },
        {
            "id": 1075,
            "name": "Hotels"
        },
        {
            "id": 1076,
            "name": "3 estrelles"
        }
    ],
    "address": "Viladomat 197",
    "postal_code": 8015,
    "latitude": 41.383665702777776,
    "longitude": 2.151834694444444
},

我想提出像

这样的请求
http://localhost:8000/apartments/?cats_name=Hotels

但它不起作用,从现在开始的道路会有什么想法吗? 写一个自定义过滤器? 为Category对象编写另一个ViewSet?

谢谢

2 个答案:

答案 0 :(得分:1)

Manager提供的根QuerySet描述数据库表中的所有对象。但是,通常,您只需要选择整个对象集的一部分。

但是这里你传递查询参数并过滤整个查询集

views.py

class AptViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows groups to be viewed or edited.
    """
    queryset = Apartment.objects.all()
    serializer_class = AptSerializer

    def get_queryset(self):
        queryset = super(AptViewSet, self).get_queryset()
        cats_name = self.request.query_params.get('cat_name', None)
        if cats_name:
            queryset = queryset.filter(cats__name=cats_name)
        return queryset

如果您可以按照此信息撰写自定义过滤器How to Pass kwarg to Filter

答案 1 :(得分:0)

查看查询参数过滤的this链接。

您将覆盖序列化程序中的get_queryset方法。