django源码解析之 BooleanField (二)

class BooleanField(Field):
    empty_strings_allowed = False
    default_error_messages = {
        ‘invalid‘: _(u"‘%s‘ value must be either True or False."),
    }
    description = _("Boolean (Either True or False)")

    def __init__(self, *args, **kwargs):
        kwargs[‘blank‘] = True
        if ‘default‘ not in kwargs and not kwargs.get(‘null‘):
            kwargs[‘default‘] = False
        Field.__init__(self, *args, **kwargs)

    def get_internal_type(self):
        return "BooleanField"

    def to_python(self, value):
        if value in (True, False):
            # if value is 1 or 0 than it‘s equal to True or False, but we want
            # to return a true bool for semantic reasons.
            return bool(value)
        if value in (‘t‘, ‘True‘, ‘1‘):
            return True
        if value in (‘f‘, ‘False‘, ‘0‘):
            return False
        msg = self.error_messages[‘invalid‘] % str(value)
        raise exceptions.ValidationError(msg)

    def get_prep_lookup(self, lookup_type, value):
        # Special-case handling for filters coming from a Web request (e.g. the
        # admin interface). Only works for scalar values (not lists). If you‘re
        # passing in a list, you might as well make things the right type when
        # constructing the list.
        if value in (‘1‘, ‘0‘):
            value = bool(int(value))
        return super(BooleanField, self).get_prep_lookup(lookup_type, value)

    def get_prep_value(self, value):
        if value is None:
            return None
        return bool(value)

    def formfield(self, **kwargs):
        # Unlike most fields, BooleanField figures out include_blank from
        # self.null instead of self.blank.
        if self.choices:
            include_blank = (self.null or
                             not (self.has_default() or ‘initial‘ in kwargs))
            defaults = {‘choices‘: self.get_choices(
                                       include_blank=include_blank)}
        else:
            defaults = {‘form_class‘: forms.BooleanField}
        defaults.update(kwargs)
        return super(BooleanField, self).formfield(**defaults)

看起来,BooleanField 要比复杂的多,我们只分析其中的

to_python 函数

 1     def to_python(self, value):
 2         if value in (True, False):
 3             # if value is 1 or 0 than it‘s equal to True or False, but we want
 4             # to return a true bool for semantic reasons.
 5             return bool(value)
 6         if value in (‘t‘, ‘True‘, ‘1‘):
 7             return True
 8         if value in (‘f‘, ‘False‘, ‘0‘):
 9             return False
10         msg = self.error_messages[‘invalid‘] % str(value)
11         raise exceptions.ValidationError(msg)

函数获得一个参数value,判断value是不是 (True,False,1, 0)中的一个,如果是,返回True或False。

下面同理,在value是字符串的情况下,判断value的值  是不是 (‘t‘, ‘True‘, ‘1‘) 中的一个,是则返回 True...

如果执行到msg = XXXXX 这里,就说明 to_python执行失败了,返回错误...抛出异常...



需要注意的是:

>>> a = True
>>> b = False
>>> c = 1
>>> d = 0
>>> e = 11
>>> f = -1
>>> a in (True,False)
True
>>> b in (True,False)
True
>>> c in (True,False)
True
>>> d in (True,False)
True
>>> e in (True,False)
False
>>> f in (True,False)
False
>>> 

如果一个大于1的数,是不会 in (True,False) 中的,这和我们平时使用

>>> if 11:
    print ‘aa‘

aa
>>> 

是不同的。

时间: 2024-12-19 01:16:28

django源码解析之 BooleanField (二)的相关文章

django源码解析之 BooleanField (三)

1 def __init__(self, *args, **kwargs): 2 kwargs['blank'] = True 3 if 'default' not in kwargs and not kwargs.get('null'): 4 kwargs['default'] = False 5 Field.__init__(self, *args, **kwargs) 在看完 BooleanField 的 to_python 之后,我们来看看 __init__ 先看看我从github上co

【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新

上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源热更新 Android热更新开源项目Tinker源码解析系类之三:so热更新 转载请标明本文来源:http://www.cnblogs

JDK8源码解析 -- HashMap(二)

在上一篇JDK8源码解析 -- HashMap(一)的博客中关于HashMap的重要知识点已经讲了差不多了,还有一些内容我会在今天这篇博客中说说,同时我也会把一些我不懂的问题抛出来,希望看到我这篇博客的大神帮忙解答困扰我的问题,让我明白一个所以然来.彼此互相进步,互相成长.HashMap从jdk7到jdk8版本改变大,1.新增加的节点在链表末尾进行添加  2.使用了红黑树. 1. HashMap容量大小求值方法 // 返回2的幂次 static final int tableSizeFor(in

Django源码解析(1):启动程序

1.Django的启动 1.1.启动命令 在Django项目根目录执行启动命令,如下: python manage.py runserver 8008 1.2.执行manage.py manage.py源码: if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "middleware_demo.settings") try: from django.

django源码解析之BigIntegerField (一)

要分析django的源码,来更深入的学习django,是一个不错的方法,可惜需要大量的时间. 所以,能分析多少就是多少吧. 本次源码分析以1.4.16为基础. 用sublime 打开下载的源码,使用 Find in Folder,查找BigIntegerField 在其中可以看到这样的代码: 1 1005 def formfield(self, **kwargs): 2 1006: defaults = {'min_value': -BigIntegerField.MAX_BIGINT - 1,

android源码解析之(二)-->异步任务AsyncTask

android的异步任务体系中还有一个非常重要的操作类:AsyncTask,其内部主要使用的是java的线程池和Handler来实现异步任务以及与UI线程的交互.本文主要解析AsyncTask的的使用与源码. 首先我们来看一下AsyncTask的基本使用: class MAsyncTask extends AsyncTask<Integer, Integer, Integer> { @Override protected void onPreExecute() { super.onPreExe

Mybaits 源码解析 (十二)----- Mybatis的事务如何被Spring管理?Mybatis和Spring事务中用的Connection是同一个吗?

不知道一些同学有没有这种疑问,为什么Mybtis中要配置dataSource,Spring的事务中也要配置dataSource?那么Mybatis和Spring事务中用的Connection是同一个吗?我们常用配置如下 <!--会话工厂 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name=&qu

Android 10大开源常用框架源码解析 系列 (二)网络框架之一 OkHttp杂题

1.Android基础网络编程:socket.HttpClient.HttpURLConnection     1.1 Socket 定义 是一个对TCP/IP协议进行封装的编程调用接口,本身不是一种协议是接口Api!!     成堆出现,一对套接字:包括ip地址和端口号   基于应用层和传输层抽象出来的一个层.App可以通过该层发送.接收数据,并通过Socket将App添加到网络当中 简单来说就是应用与外部通信的端口,提供了两端数据的传输的通道     1.2 Socket通信模型 基于TCP

Django源码解析:setting.py

1. setting.py文件 我们在django项目中,新建一个app的时候,都会有一个setting.py文件,里面包含了整个项目所有的配置,包括apps,中间键,数据库等等,django是如何将该setting文件利用起来的呢. 2. 从setting.py配置文件到Setting类 (1)启动的时候,指定默认的配置文件 django在启动的时候,会调用manage.py文件运行server的实例,在文件一开始的时候,manage.py会调用下面代码 os.environ.setdefau