让Django的BooleanField支持字符串形式的输入方式
本文介绍如何在Django中让BooleanField接受字符串形式的布尔值。针对Swift Alamofire上传Multipartform时Bool转Data导致的编码问题,通过将Bool转为"0"或"1"字符串上传,并重写BooleanField的get_prep_value方法,实现自动将字符串转换为正确的布尔值,避免后台赋值错误。
Django BooleanField 字符串输入问题背景
在Django中,你可以将字符串形式的数值赋值给IntegerField,Django会自动将其转换为int类型。
然而,BooleanField并不支持这种隐式转换,它仅接受True、False、0或1(注:在Python中True等价于1,False等价于0)。
这在许多网络参数上传场景中带来不便,因为为了操作方便,常需将布尔型参数转换为字符串形式进行上传。
Swift Alamofire 上传中的编码挑战
一个典型场景是使用Swift的Alamofire框架通过upload方法上传Multipartform数据。由于form参数只能添加Data类型的参数,直接将Bool类型转换为Data非常繁琐,且容易引发编码类型问题。
例如,采用如下方式进行转换:
let dataToUpload = Data(bytes: boolVal, count: MemoryLayout<Bool>.size)
以这种形式上传后,Django接收到的该字段值会是"\x00"(代表False)或"\x01"(代表True),从而导致编码类型错误。
因此,一种较为便捷的方法是将bool型变量先转换为字符串再上传。
let toText = boolVal ? "1" : "0" form.append(toText.data(using: String.Encoding.utf8, allowLossyConversion: false)!, withName: key)
虽然这种方法避免了编码问题,但在后台直接将该字段赋值给BooleanField时,结果将永远是True(这是因为将非空字符串直接通过bool()进行强制类型转换时,结果始终为True)。
一种妥协的做法是先将上传的字符型字段转换为Int,再赋值给BooleanField。
不过,这里介绍一种更整洁、更一劳永逸的方法:重新定义BooleanField的行为,在为其赋值时,自动按照我们设定的规则将字符串转换为Bool值。
重写 BooleanField 以支持字符串转换
代码如下:
from django.db.models import BooleanField as _BooleanField
class BooleanField(_BooleanField):
def get_prep_value(self, value):
if value in ("0", "false", "False"):
return False
elif value in ("1", "true", "True"):
return True
else:
return super(BooleanField, self).get_prep_value(value)
其中get_prep_value这个函数会在Django准备把字段的值写入数据库时调用。
Django xadmin 配置补充
补充知识:Django xadmin 设置只读字段,设置BooleanField类型在页面中的显示位置
class MachineInfoAdmin(admin.ModelAdmin):
def get_readonly_fields(self, request, obj=None):
""" 重新定义此函数,限制普通用户所能修改的字段 """
if request.user.is_superuser:
self.readonly_fields = []
return self.readonly_fields
readonly_fields = ('machine_ip', 'status', 'user', 'machine_model', 'cache',
'cpu', 'hard_disk', 'machine_os', 'idc', 'machine_group')
二,xadmin自定义字段设置排序
def identity(self,ext):
return ext.user.get_types_display()
identity.short_description='身份'
# identity.admin_order_field = 'end_date'
# 设置列表显示字段
list_display = ['name', 'course_org', 'detail','degree','learn_times','students','fav_nums','image','click_nums','add_time']
# 设置列表查询字段
search_field = ['name', 'course_org', 'detail','degree','learn_times','students','fav_nums','image','click_nums']
# 设置列表过滤字段
list_filter = ['name', 'course_org', 'detail','degree','learn_times','students','fav_nums','image','click_nums','add_time']
# 设置显示图标
model_icon = 'fa fa-check-square' # 设置字段可以直接在列表页修改 list_editable=['desc','degree']
# 设置默认排序
ordering=['-click_nums']
# 设置详情页面只读显示
readonly_fields=['fav_nums','click_nums']
# 设置详情页面不显示某个字段
exclude=['add_time']
#自动刷新列表页面(秒数)
refresh_times = [3,5]
三,设置BooleadnField 显示和其他字段同列
1、

2、

以上这篇让Django的BooleanField支持字符串形式的输入方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













