本文介绍了Django Rest Framework ManyToMany过滤多个值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个模型,一个定义用户,另一个定义这些用户的标签.我正在使用Django Rest Framework创建API.我希望能够查询至少具有标签ID 1和2的用户.

I have two models, one defining users, the other defining labels on these users. I am using Django Rest Framework to create an API. I would like to be able to query users with at least labels ids 1 and 2.

例如,用户的标签是: [(1,2 ,,(1,2,3),(2,3),(1,3)] 我要查询返回 [((1,2),(1,2,3)] .

For instance is the users' labels are:[(1,2), (1,2,3), (2,3), (1,3)] I want the query to return [(1,2), (1,2,3)].

到目前为止,我已经通过执行以下操作来查询具有给定标签(假设ID = 1)的用户:/api/users/?labels = 1 ,但是我无法查询标签为1和2的用户.我尝试使用/api/users/?labels = 1,2 /api/users/?labels = 1& labels = 2 但它会返回一些无效用户,即没有标签1或2的用户...

So far, I've managed to query users with a given label (let's say id=1) by doing: /api/users/?labels=1, but I am unable to query users with labels 1 and 2. I've tried /api/users/?labels=1,2 or /api/users/?labels=1&labels=2 but it return some invalid users, i.e. users without labels 1 or 2...

欢迎任何帮助.

谢谢,
Dimitry

Thanks,
Dimitry

Github测试仓库:

https://github.com/TheDimLebowski/drf-m2m-filter

代码:

class Label(models.Model):
    name = models.CharField(max_length = 60)

class User(models.Model):
    labels = models.ManyToManyField(Label)

filters.py

class UserFilter(django_filters.FilterSet):
    labels = django_filters.filters.BaseInFilter(
        name='labels',
        lookup_type='in',
    )

    class Meta:
        model = User
        fields = ('labels',)

serializers.py

class LabelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Label
        fields = ('id','name')

class UserSerializer(serializers.ModelSerializer):
    labels = LabelSerializer(many = True)
    class Meta:
        model = User
        fields = ('labels',)

views.py

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filter_class = UserFilter
    filter_fields = ('labels',)

推荐答案

您可以链接过滤器.例如,如果您需要所有标签都包含 1 2 值的用户,则可以编写如下查询:

You can chain filters. For example, if you need all users which labels contain both 1 and 2 values, you can write a query like so:

User.objects.filter(labels=1).filter(labels=2)

django-filters 默认情况下不支持此类查询,因此您需要自定义过滤器.

django-filters does not support queries like this by default so you need a custom filter.

class M2MFilter(django_filters.Filter):

    def filter(self, qs, value):
        if not value:
            return qs
    
        values = value.split(',')
        for v in values:
            qs = qs.filter(labels=v)
        return qs


class UserFilter(django_filters.FilterSet):
    labels = M2MFilter(name='labels')

    class Meta:
        model = User
        fields = ('labels',)

现在,您可以用逗号分隔标签ID,并获得所需的信息

Now you can write labels id's comma-separated and get exactly what you need

/api/users/?labels=1,2

关于m2m查询的好答案

这篇关于Django Rest Framework ManyToMany过滤多个值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-10 06:59