Introduction to Django-Filter and How to Implement Tricky Requirements
Django-Filter is a very useful third-party library that makes great use of Django ORM's features. You can extend existing APIs with very little code to implement various filtering functions~ Scenario Part of the Model definition code. You can see that the requirement model includes these three fields: keyword keyword, region region, and requirement status require_status class Require(models.Model): Requirement keyword =
目录9 个章节
Django-Filter is a very useful third-party library that makes great use of Django ORM's features. You can extend existing APIs with very little code to implement various filtering functions~
Scenario
Part of the Model definition code. You can see that the requirement model includes these three fields: keyword keyword, region region, and requirement status require_status
class Require(models.Model):
"""需求"""
keyword = models.CharField('需求关键字', max_length=1000, blank=True)
region = models.ForeignKey(Region, verbose_name='落地实施区域', null=True, on_delete=models.SET_NULL)
require_status = models.IntegerField('需求进行状态', choices=RequireStatusChoice.choices)
Next is the ViewSet code. In DRF, after simple route configuration you can get the requirement list, but real-world scenarios definitely require more than this
class RequireViewSet(viewsets.ModelViewSet):
"""需求记录"""
serializer_class = RequireSerializer
queryset = Require.objects.all()
The product needs many features. For this requirement module specifically, we need:
- Search requirements by keyword
- Filter requirements by implementation region
- Filter requirements by requirement progress status
If we were using Java, we'd definitely have to dutifully write a few extra lines of code to implement this. But! Life is short, I use Python!
How could we Python users possibly yield to implementing such a simple feature? When it's time to be lazy, we must be lazy. If there's no way to be lazy, we still have to force ourselves to be lazy hhh~
Simple Usage of Django-Filter
Let's see how we implement this with Django-Filter. First, install Django-Filter:
pip install django-filter
Add it to settings.py:
INSTALLED_APPS = [
...
'django_filters',
]
Then just configure it in the ViewSet:
from django_filters.rest_framework import DjangoFilterBackend
class RequireViewSet(viewsets.ModelViewSet):
"""需求记录"""
serializer_class = RequireSerializer
queryset = Require.objects.all()
filter_backends = [DjangoFilterBackend, SearchFilter]
# 参与分类筛选的字段
filter_fields = ['require_status', 'region']
# 参与搜索的字段: search=关键词
search_fields = ['keyword']
After configuration, you can filter and search on top of the original API. Assume the endpoint is: http://127.0.0.1/require/
Search
http://127.0.0.1/require/?search=关键词
Filter by Region
http://127.0.0.1/require/?region=1
Filter by Requirement Status
http://127.0.0.1/require/?require_status=2
The result is perfect. Just simple configuration can implement so many features. That's the benefit of being lazy (standing on the shoulders of giants). These CRUD features don't really involve much technical skill anyway—the authors of the framework and third-party libraries have already implemented them for us, so we can just use them~
But then the frontend folks came up with a new requirement: the requirement status require_status needs to filter requirements with multiple statuses at once, for example filtering requirements with status numbers 2-9 at the same time... This is a pain. Django-Filter only supports one by default. What to do...
But don't worry. I believe no problem can stump my Stack Overflow, so I searched a bunch of keywords, tried four or five methods provided by helpful netizens, and sure enough found the best solution...
Filtering Multiple Values at Once
First, define a custom Filter. Here I use commas to split each parameter. The code is as follows:
from django_filters import Filter,FilterSet
class ListFilter(Filter):
def filter(self, qs, value):
if not value:
return qs
# For django-filter versions < 0.13, use lookup_type instead of lookup_expr
self.lookup_expr = 'in'
values = value[0:1000].split(',')
return super(ListFilter, self).filter(qs, values)
class RequireStatusFilter(FilterSet):
require_statuses = ListFilter(field_name='require_status')
class Meta:
from apps.require.models import Require
model = Require
fields = ['require_statuses', 'region']
Then modify our ViewSet. You can see that filter_fields is no longer needed, because it's already defined in RequireStatusFilter
class RequireViewSet(viewsets.ModelViewSet):
"""需求记录"""
serializer_class = RequireSerializer
queryset = Require.objects.all()
permission_classes = [permissions.IsAuthenticated]
filter_backends = [DjangoFilterBackend, SearchFilter]
filter_class = RequireStatusFilter
search_fields = ['keyword']
How to Use
Absolutely delightful
http://127.0.0.1/require/?region=1&require_status=1,2,3,4,5,6,7,8,9
Gossip
Finally, a bit of gossip: today the father of Python tweeted that he joined Microsoft, and the father of Delphi/C#/TypeScript posted congratulations in the comments, hahaha

References
- Stack Overflow question: https://stackoverflow.com/questions/31029792/djangofilterbackend-with-multiple-ids
- Official documentation: https://django-filter.readthedocs.io/
_EOF_
Introduction to Django-Filter and How to Implement Tricky Requirements
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
Django全文检索实现:HayStack-+-Whoosh-+-Jieba
涉及到的工具 haystack是django的开源搜索框架,该框架支持**Solr**, Elasticsearch, Whoosh, **Xapian搜索引擎,不用更改代码,直接切换引擎,减少代码量。 搜索引擎使用Whoosh,这是一个由纯Python实现的全文搜索引擎,没有二进制文件等,比较小巧,配置比较简单,当然性能自然略低。 中文分词Jieba,由于Whoosh自带的是英文分词,对中文的分
2022-08-26 · Django · 约 1 分钟
实测 Django 6.0:模版片段、后台任务、CSP 安全,三大特性体验报告
呵,连WebSocket都没塞进去就敢叫大版本更新?不过模版片段和内置后台任务总算让Django像个现代框架了,至少写HTMX时不用再到处塞碎片文件。原生CSP?早该有了。至于抛弃Python 3.11——跟不上时代的版本留着也是累赘。
2026-01-20 · Django · 约 1 分钟
给Django的Admin添加自定义Action-并移除需要选择对象的限制
前言 不得不说,Django的Admin真的给开发带来很多便利,这不,我又来折腾了,这次是添加自定义的action 这个自定义的Action可以看看官方文档的介绍,很详细,不再赘述。 https://docs.djangoproject.com/en/3.0/ref/contrib/admin/actions/ 界面效果 Django默认的添加完action是要选择下面的对象才能提交的,不过我不需
2022-08-26 · Django · 约 1 分钟
Django中「强行」使用MVVM设计模式
扫盲 首先带大家了解一下什么是MVVM模式: 什么是MVVM?MVVM是Model-View-ViewModel的缩写。 MVVM是MVC的增强版,实质上和MVC没有本质区别,只是代码的位置变动而已 从名字上看,MVVM比MVC架构中多了一个ViewModel,没错,就是这个ViewModel,他是MVVM相对于MVC改进的核心思想。在开发过程中,由于需求的变更或添加,项目的复杂度越来越高,代码量
2021-12-18 · Django · 约 1 分钟
讨论
共 0 条加载评论中…