将 django-filter 与对象一起使用 url_params

use django-filter with object url_params

我已经在我的 Django-rest-framework 服务器上成功实现了 django-filter。

我有以下filter_class

filters.py

class EmploymentFilter(filters.FilterSet):
    class Meta:
        model = EmploymentCheck
        fields  = ['instructions',]

views.py

class EmploymentCheckViewSet(viewsets.ModelViewSet):
    pagination_class = ContentRangeHeaderPagination
    serializer_class = EmploymentCheckSerializer
    queryset = EmploymentCheck.objects.all()
    filter_class = EmploymentFilter

当我以

发送获取请求时过滤器起作用

/employmentcheck/?instructions=2

不过,我用react-admin实现了一个前端。 我的前端发送一个带有 url_params 作为对象

的请求

/employmentcheck/?filter={"instruction_id":"2"}&range=[0,24]&sort=["id","DESC"]/

注意 URL 如何指定过滤器对象,其中定义了要过滤的参数。

我的问题是,在不更改客户端的 URL 模式的情况下,如何以及在何处过滤我的模型? 同样欢迎涵盖我的问题范围的任何其他建议

Models.py

class EmploymentCheck(models.Model):
    instructions = models.ForeignKey(Instruction, on_delete=models.CASCADE, null=True)

我只是省略了 filter_class,而是覆盖了视图集的 get_queryset() 方法。

Allow me to make some changes, the commented out code would fail if you sent a request with no 'filter' query params. e.g GET:/api/employee/ as opposed to GET:/api/employee/?filter{"instruction"=""}

所以我选择检查 query_params.get('key') 是否为 none,如果是,我传递一个空字符串。

Any better pythonic way of handling this is encouraged

ViewSet

class EmploymentCheckViewSet(viewsets.ModelViewSet):
    serializer_class = EmploymentCheckSerializer

    def get_queryset(self):
        queryset = EmploymentCheck.objects.all()

        if self.request.query_params.get('filter') is None:
            return queryset #return the queryset as is
        else:
        _instructions = self.request.query_params.get('filter')            #returned as a string
        _instructions = json.loads(_instructions)#convert to dictionary
        if queryset and any(_instructions):
            queryset = queryset.filter(instructions = _instructions['instruction_id'])
            return queryset

注意:当您覆盖 get_queryset 时,您必须在 app.urls.py 中显式定义 router.register 方法的 base_name 参数。参考django-rest-framework routers.

urls.py

router = DefaultRouter()
router.register(r'employmentcheck', views.EmploymentCheckViewSet, 'EmploymentCheck')#explicitly set the base_name attribute when the viewset defines a custom get_queryset method