python - 在 django-filters 中为过滤 ChoiceField 创建别名
问题描述
对于某些模型,我有以下过滤器集:
class MyModel(models.Model):
STATUS_ACTIVE = 0
STATUS_DONE = 1
STATUSES = (
(STATUS_ACTIVE, 'Active'),
(STATUS_DONE, 'Done'),
)
status = models.IntegerField(choices=STATUSES, default=STATUS_ACTIVE)
class ModelFilter(FilterSet):
status = ChoiceFilter(choices=MyModel.STATUSES)
class Meta:
model = MyModel
fields = (
'status',
)
当我向某些 API 发出请求时,我应该使用 status 作为数字 - /app/model?status=0
。
如何为其制作别名,以便我可以使用/app/model?status=active
而不是数字,而无需更改模型?
解决方案
最后我在库中找到了源代码并创建了这个解决方案:
class AliasesChoiceField(ChoiceField):
def valid_value(self, value):
for _, v in self.choices:
if value == v or str(value) == str(v):
return True
return False
class AliasesChoiceFilter(ChoiceFilter):
field_class = AliasesChoiceField
def filter(self, qs, value):
for val, alias in self.extra['choices']:
if value == alias:
return super(AliasesChoiceFilter, self).filter(qs, val)
return super(AliasesChoiceFilter, self).filter(qs, value)
在AliasesChoiceField.valid_value()
我刚刚复制了基本方法并进行了简单的更改以正确验证值。
AliasesChoiceFilter
用于field_class
验证,所以我只需将其替换为ChoiceFilter
, 并将filter()
方法更改为我选择的参数的正确映射。
最后我的模型看起来像这样
class ModelFilter(FilterSet):
STATUSES = (
(MyModel.STATUS_ACTIVE, 'active'),
(MyModel.STATUS_DONE, 'done')
)
status = AliasesChoiceFilter(choices=STATUSES)
并且 API 路由/app/model?status=active
正常工作,设置正确的过滤状态。
但!此解决方案不适用于 Django Admin 或通过 web api 界面,因为它将提供真实值,并且会尝试传递0
而不是active
推荐阅读
- plotly - 将 CSV 文件从 Excel 导入 Plot.ly 时出现日期问题
- python - reset_mock() 得到了一个意外的关键字参数“return_value”——为什么?
- javascript - 将数据从 json 保存到文本文件
- javascript - 在反应中改变值时使文本变为白色?反应弹簧?
- python - 历元上的恒定精度
- javascript - 如何显示使用快递发布帖子的时间
- amazon-web-services - 尝试设置一个测验,从 S3 存储桶中获取正确的图像以获取正确的问题
- google-cloud-platform - 使用 Terraform 部署数据流
- javascript - 如何将 sapper 应用程序中的 stripe.js 导入我的 preload() 或 onMount()
- java - 查找不存在的最佳搜索算法