如何在django-filter中用choice field 的 value 值过滤对象
如果我们有这样一个model:
class IPInfoModel(models.Model):
TYPE_INTRANET = 1
TYPE_INTERNET = 2
IP_TYPES = (
(TYPE_INTRANET, u'内网'),
(TYPE_INTERNET, u'外网'),
)
ip = models.GenericIPAddressField("IP", unique=True)
ip_type = models.SmallIntegerField(choices=IP_TYPES)
然后我使用 rest_frame_work + django_filter 做API
from django_filters import rest_framework as django_filters
class IPInfoFilter(django_filters.FilterSet):
ip_type = django_filters.ChoiceFilter(choices=IPInfoModel.IP_TYPES)
class Meta:
model = IPInfoModel
fields = ["ip_type",]
class IPInfoViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
queryset = IPInfoModel.objects.all()
serializer_class = IPInfoSerializer
filter_class = IPInfoFilter
但是这样在过滤 ip_type 时,只能使用choice field 的 key 值 “1”, “2” 来进行过滤。
这样很不直观,那么如何才能使用choice field 的 value 值 “内网”, “外网” 来过滤对象呢?
方法一
我的做法是通过自定义一个 ChoiceValueFilter,并覆盖 Django 的 forms.ChoiceField 中的验证函数 valid_value 来实现。
代码如下:
from django import forms
from django_filters import rest_framework as django_filters
from django_filters.conf import settings
class ChoiceValueField(forms.ChoiceField):
def valid_value(self, value):
text_value = str(value)
for k, v in self.choices:
if value == v or text_value == str(v):
return True
return False
class ChoiceValueFilter(django_filters.Filter):
field_class = ChoiceValueField
def __init__(self, *args, **kwargs):
self.null_value = kwargs.get('null_value', settings.NULL_CHOICE_VALUE)
self.choices = kwargs.get('choices')
super().__init__(*args, **kwargs)
def filter(self, qs, value):
value_map = {v: k for k, v in self.choices}
return qs.filter(ip_type=value_map[value]) if value else qs
这样做的好处是
- 比较通用,只要传入对应choice field 的元祖就可以使用了。
- 仍然会对传入的参数进行验证,保证只能使用 choice field 的 value 值中已有的值进行过滤。
然后改写原有的IPInfoFilter, 改为使用 ChoiceValueFilter 就可以了。
class IPInfoFilter(django_filters.FilterSet):
ip_type = ChoiceValueFilter(choices=IPInfoModel.IP_TYPES)
class Meta:
model = IPInfoModel
fields = ["ip_type", "is_vip"]
方法二
也可以通过自定义filter的方法来实现
参考: https://django-filter.readthedocs.io/en/master/ref/filters.html#method
class IPInfoFilter(django_filters.FilterSet):
ip_type = django_filters.CharFilter(method='filter_ip_type')
def filter_ip_type(self, queryset, name, value):
# create a dictionary string -> integer
value_map = {v: k for k, v in IPInfoModel.IP_TYPES.items()}
# get the integer value for the input string
value = value_map[value]
return queryset.filter(ip_type=value)
如何在django-filter中用choice field 的 value 值过滤对象的更多相关文章
- Django filter中用contains 在mysql中的问题
用PYTHON ,DJANGO 做站,在通常的情况下,需要用到 orM 的查询方法,比如object.filter(tag__contains='keywords').... 在这种情况下,如果你跟踪 ...
- 深入浅出SharePoint——获取Choice Field的Mapping value
list field对应的caml定义如下 <Field Type="Choice" DisplayName="Inspection Result" Re ...
- 如何在Django模型中管理并发性 orm select_for_update
如何在Django模型中管理并发性 为单用户服务的桌面系统的日子已经过去了 - 网络应用程序现在正在为数百万用户提供服务,许多用户出现了广泛的新问题 - 并发问题. 在本文中,我将介绍在Django模 ...
- filter 中用spring StopWatch 监控请求执行时间
在filter中用spring stopWatch 来统计每个请求的执行时间: 虽然在firefox 中可以清楚的看到每个请求的执行时间,但是为了测试,记录日志, 方便以后查询维护. 还是必要的,下面 ...
- Flask WTForm disable choice field
Flask disable choice field ChoiceField = { render_kw={'disabled':''} } form.my_field.render_kw = {'d ...
- Django——8 关系表的数据操作 表关联对象的访问 多表查询
Django 关系表中的数据操作 表关联对象的访问 关联对象的add方法 create方法 remove方法 clear方法 多表查询 查询补充 聚合查询 分组查询 F查询 Q查询 关系表的数据操作 ...
- Django model.py表单的默认值 默认允许为空
Field.null 默认是null=False,这时不能传入NULL型数据,但是可以是空字符. 如果BooleanField中想要null数据类型,可以选择NullBooleanField Fi ...
- Filter中排除对指定URL的过滤
1. 我们可以在web.xml中配置filter来对指定的URL进行过滤,进行一些特殊操作如权限验证等. <!– session过滤filter –> <filter> < ...
- django - request.POST和request.body获取值时出现的情况
django request.POST / request.body 当request.POST没有值 需要考虑下面两个要求 1.如果请求头中的: Content-Type: application/ ...
随机推荐
- NOIP--模拟—————神奇的幻方
神奇的幻方 题目描述 幻方是一种很神奇的 N*N 矩阵:它由数字 1,2,3,-N x N 构成,且每行.每列及两条对角线上的数字之和都相同. 当 N 为奇数时,我们可以通过下方法构建一个幻方: 首先 ...
- js递归生成树形下拉菜单
需求:我需要把一个单表的数据转换成类似菜单那种如图所示:我呢需要把这个菜单树放入到下框里面去如图所示: 下面是实现思路:1.第一步1.1var afTypeJson=${afTypeJson}// 这 ...
- 写作环境搭建(git+github+markdown+jekyll)
转载自: https://site.douban.com/196781/widget/notes/12161495/note/264946576/ 2013-03-04 19:33:10 --- ...
- python中,字符串前的u,b,r字符的含义
1.字符串前加 u 例:u"我是含有中文字符组成的字符串." 作用: 后面字符串以 Unicode 格式 进行编码,一般用在中文字符串前面,防止因为源码储存格式问题,导致再次使用时 ...
- 实验四《Android程序设计》
实验四<Android程序设计> 一.实验内容 1.Android Stuidio的安装测试 2.Activity测试 3.UI测试 4.布局测试 5.事件处理测试 二.实验步骤 第一部分 ...
- HTML去除多余空白区域的方法
在head标记中添加html,body{height:100%;}即可. 实例如下 <head><style>html,body{height:90%;}</style& ...
- ASP.NET Core搭建多层网站架构【13-扩展之支持全球化和本地化多语言】
2020/02/03, ASP.NET Core 3.1, VS2019, ResXManager 摘要:基于ASP.NET Core 3.1 WebApi搭建后端多层网站架构[13-扩展之支持全球化 ...
- ABC156D
[题目链接]https://atcoder.jp/contests/abc156/tasks/abc156_d 简单数论问题,题意就是有n个数,不能组成a与b个数,问有多少种组合方式 那就是C(n,1 ...
- 商品呢拖拽到购物车,appendChild的剪切功能
今天来到了妙味课堂的html5课程的第2张的第8节,讲的是把商品拖拽到购物车的演示.其中有一个关于appendChild的使用,,每次拖拽都会触发这个方法,但是每次之后,却还是只有一个总价,好吧,说不 ...
- python opencv:绘图 基本图形
参数说明 • img:你想要绘制图形的那幅图像. • color:形状的颜色.以 RGB 为例,需要传入一个元组,例如:( 255,0,0)代表蓝色.对于灰度图只需要传入灰度值. • thicknes ...