【问题标题】:how to use django rest filtering with mongoengine如何在 mongoengine 中使用 django rest 过滤
【发布时间】:2015-10-17 06:29:44
【问题描述】:

您好,我正在使用 mongodb 启动 django 1.8.3,使用 mongo 引擎创建 rest api。

我正在使用 rest_framework_mongoengine 来执行此操作。
我想使用 DjangoFilterBackend 的一个功能。

我的代码是:

models.py:

from mongoengine import *    
from django.conf import settings    
connect(settings.DBNAME)

class Client(Document):
    name = StringField(max_length=50)
    city = StringField(max_length=50)
    country = StringField(max_length=200, verbose_name="Country")
    address = StringField(default='')

序列化器.py

from client.models import Client    
from rest_framework_mongoengine.serializers import DocumentSerializer    


class ClientSerializer(DocumentSerializer):
    class Meta:
        model = Client
        depth = 1

views.py

from rest_framework_mongoengine.generics import *    
from rest_framework import filters    


class ClientList(ListCreateAPIView):
    serializer_class = ClientSerializer
    queryset = Client.objects.all()
    filter_backends = (filters.DjangoFilterBackend,)
    filter_fields = ('name',)

我开始出错 QuerySet 对象没有属性模型

不知道哪里出错了。如果我删除 filter_field 它可以工作,但我不能使用过滤功能。

任何帮助都会很有用

【问题讨论】:

标签: django mongodb python-2.7 django-rest-framework mongoengine


【解决方案1】:

您还可以通过覆盖get_queryset() 方法并创建通用过滤函数来执行过滤。

在这里,我们将视图中的过滤字段元组指定为my_filter_fields,我们要对其执行过滤。然后在我们的get_queryset() 中,我们调用一个函数get_kwargs_for_filtering()

get_kwargs_for_filtering() 函数遍历my_filter_fields 中定义的字段,并检查是否在query_params 中传递。如果找到该字段,则在字典filtering_kwargs 中设置具有字段名称和值作为检索值的键。迭代结束后,这个filtering_kwargs字典返回给get_queryset()方法。

这个filtering_kwargs字典用于过滤查询集。

from rest_framework_mongoengine.generics import *    
from rest_framework import filters    


class ClientList(ListCreateAPIView):
    serializer_class = ClientSerializer
    my_filter_fields = ('name', 'country') # specify the fields on which you want to filter

    def get_kwargs_for_filtering(self):
        filtering_kwargs = {} 
        for field in  self.my_filter_fields: # iterate over the filter fields
            field_value = self.request.query_params.get(field) # get the value of a field from request query parameter
            if field_value: 
                filtering_kwargs[field] = field_value
        return filtering_kwargs 

    def get_queryset(self):
        queryset = Client.objects.all() 
        filtering_kwargs = self.get_kwargs_for_filtering() # get the fields with values for filtering 
        if filtering_kwargs
            queryset = Client.objects.filter(**filtering_kwargs) # filter the queryset based on 'filtering_kwargs'
        return queryset

【讨论】:

  • 如果您覆盖 get_queryset() 方法而不是假设您想为模型中的所有项目应用过滤器,而不是您必须手动检查所有项目,例如假设我是否必须对名称 + 国家/地区执行过滤器 +城市比再次我将检查所有。此外,可选处理会有所不同 寻找通用解决方案。感谢您的宝贵时间
  • 用通用解决方案更新了 ans。检查它是否有帮助。
  • 谢谢@Rahul Gupta 这正是我正在寻找的方式
  • 如果这里的客户是一个 mongo 文档并且排除的工作方式是否相同?
  • @F_Ashik Mongoengine 的 .exclude() 与 Django QuerySet 的 .exclude() 有点不同。在这里查看docs.mongoengine.org/…
【解决方案2】:

这是完成这项工作的好方法。 首先,你应该安装 django_mongoengine_filter rest_framework_mongoengine

pip install django_mongoengine_filter 
pip install rest_framework_mongoengine

其次,您可以像这样编写您的所有者过滤器:

import django_mongoengine_filter as filters

from app.models import User

class UserFilter(filters.FilterSet):
    class Meta:
        model = User
        fields = ['name']

最后,您可以在视图类中像这样使用 UserFilter:

from app.models import User
from app.serializer import UserS  # use rest_framework_mongoengine to write serializer
from app.filters import UserFilter


class UserVS(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserS
    # override filter_queryset function
    def filter_queryset(self, queryset):
        filter = UserFilter(self.request.query_params, queryset=queryset)
        return filter.qs


【讨论】:

    猜你喜欢
    • 2017-05-16
    • 1970-01-01
    • 2016-09-08
    • 1970-01-01
    • 2012-01-10
    • 1970-01-01
    • 2014-09-30
    • 1970-01-01
    • 2018-12-04
    相关资源
    最近更新 更多