Python的Django框架中设置日期和字段可选的方法


Posted in Python onJuly 17, 2015

设置字段可选

在摆弄了一会之后,你或许会发现管理工具有个限制:编辑表单需要你填写每一个字段,然而在有些情况下,你想要某些字段是可选的。 举个例子,我们想要Author模块中的email字段成为可选,即允许不填。 在现实世界中,你可能没有为每个作者登记邮箱地址。

为了指定email字段为可选,你只要编辑Book模块(回想第五章,它在mysite/books/models.py文件里),在email字段上加上blank=True。代码如下:

class Author(models.Model):
  first_name = models.CharField(max_length=30)
  last_name = models.CharField(max_length=40)
  email = models.EmailField(**blank=True** )

这些代码告诉Django,作者的邮箱地址允许输入一个空值。 所有字段都默认blank=False,这使得它们不允许输入空值。

这里会发生一些有趣的事情。 直到现在,除了__unicode__()方法,我们的模块充当数据库中表定义的角色,即本质上是用Python的语法来写CREATE TABLE语句。 在添加blank=True过程中,我们已经开始在简单的定义数据表上扩展我们的模块了。 现在,我们的模块类开始成为一个富含Author对象属性和行为的集合了。 email不但展现为一个数据库中的VARCHAR类型的字段,它还是页面中可选的字段,就像在管理工具中看到的那样。

当你添加blank=True以后,刷新页面Add author edit form (http://127.0.0.1:8000/admin/books/author/add/ ),将会发现Email的标签不再是粗体了。 这意味它不是一个必填字段。 现在你可以添加一个作者而不必输入邮箱地址,即使你为这个字段提交了一个空值,也再不会得到那刺眼的红色信息“This field is required”。
设置日期型和数字型字段可选

虽然blank=True同样适用于日期型和数字型字段,但是这里需要详细讲解一些背景知识。

SQL有指定空值的独特方式,它把空值叫做NULL。NULL可以表示为未知的、非法的、或其它程序指定的含义。

在SQL中, NULL的值不同于空字符串,就像Python中None不同于空字符串("")一样。这意味着某个字符型字段(如VARCHAR)的值不可能同时包含NULL和空字符串。

这会引起不必要的歧义或疑惑。 为什么这条记录有个NULL,而那条记录却有个空字符串? 它们之间有区别,还是数据输入不一致? 还有: 我怎样才能得到全部拥有空值的记录,应该按NULL和空字符串查找么?还是仅按字符串查找?

为了消除歧义,Django生成CREATE TABLE语句自动为每个字段显式加上NOT NULL。 这里有个生成Author模块的例子:

CREATE TABLE "books_author" (
  "id" serial NOT NULL PRIMARY KEY,
  "first_name" varchar(30) NOT NULL,
  "last_name" varchar(40) NOT NULL,
  "email" varchar(75) NOT NULL
)
;

在大多数情况下,这种默认的行为对你的应用程序来说是最佳的,因为它可以使你不再因数据一致性而头痛。 而且它可以和Django的其它部分工作得很好。如在管理工具中,如果你留空一个字符型字段,它会为此插入一个空字符串(而* 不是*NULL)。

但是,其它数据类型有例外:日期型、时间型和数字型字段不接受空字符串。 如果你尝试将一个空字符串插入日期型或整数型字段,你可能会得到数据库返回的错误,这取决于那个数据库的类型。 (PostgreSQL比较严禁,会抛出一个异常;MySQL可能会也可能不会接受,这取决于你使用的版本和运气了。)在这种情况下,NULL是唯一指定空值的方法。 在Django模块中,你可以通过添加null=True来指定一个字段允许为NULL。

因此,这说起来有点复杂: 如果你想允许一个日期型(DateField、TimeField、DateTimeField)或数字型(IntegerField、DecimalField、FloatField)字段为空,你需要使用null=True * 和* blank=True。

为了举例说明,让我们把Book模块修改成允许 publication_date为空。修改后的代码如下:

class Book(models.Model):
  title = models.CharField(max_length=100)
  authors = models.ManyToManyField(Author)
  publisher = models.ForeignKey(Publisher)
  publication_date = models.DateField(**blank=True, null=True** )

添加null=True比添加blank=True复杂。因为null=True改变了数据的语义,即改变了CREATE TABLE语句,把publication_date字段上的NOT NULL删除了。 要完成这些改动,我们还需要更新数据库。

出于某种原因,Django不会尝试自动更新数据库结构。所以你必须执行ALTER TABLE语句将模块的改动更新至数据库。 像先前那样,你可以使用manage.py dbshell进入数据库服务环境。 以下是在这个特殊情况下如何删除NOT NULL:

ALTER TABLE books_book ALTER COLUMN publication_date DROP NOT NULL;

(注意:以下SQL语法是PostgreSQL特有的。)

我们将在第十章详细讲述数据库结构更改。

现在让我们回到管理工具,添加book的编辑页面允许输入一个空的publication date。

Python 相关文章推荐
python实现用户答题功能
Jan 17 Python
Python解决走迷宫问题算法示例
Jul 27 Python
11个Python3字典内置方法大全与示例汇总
May 13 Python
浅谈python多进程共享变量Value的使用tips
Jul 16 Python
Django RBAC权限管理设计过程详解
Aug 06 Python
Python 从subprocess运行的子进程中实时获取输出的例子
Aug 14 Python
python 爬虫百度地图的信息界面的实现方法
Oct 27 Python
Python实现分数序列求和
Feb 25 Python
python GUI库图形界面开发之PyQt5中QWebEngineView内嵌网页与Python的数据交互传参详细方法实例
Feb 26 Python
Kears 使用:通过回调函数保存最佳准确率下的模型操作
Jun 17 Python
python3.7 openpyxl 在excel单元格中写入数据实例
Sep 01 Python
详解Pytorch显存动态分配规律探索
Nov 17 Python
Python的Django框架下管理站点的基本方法
Jul 17 #Python
Django中更新多个对象数据与删除对象的方法
Jul 17 #Python
Django框架中数据的连锁查询和限制返回数据的方法
Jul 17 #Python
Django中对数据查询结果进行排序的方法
Jul 17 #Python
在Python的Django框架中获取单个对象数据的简单方法
Jul 17 #Python
Python的Django框架中的数据过滤功能
Jul 17 #Python
在Python的Django框架中更新数据库数据的方法
Jul 17 #Python
You might like
PHP中通过HTTP_USER_AGENT判断是否为手机移动终端的函数代码
2013/02/14 PHP
mysql_connect localhost和127.0.0.1的区别(网络层阐述)
2015/03/26 PHP
php使用变量动态创建类的对象用法示例
2017/02/06 PHP
PHP simplexml_load_file()函数讲解
2019/02/03 PHP
javascript 主动派发事件总结
2011/08/09 Javascript
js实现兼容IE、Firefox的图片缩放代码
2015/12/08 Javascript
纯前端JavaScript实现Excel IO案例分享
2016/08/26 Javascript
js代码延迟一定时间后执行一个函数的实例
2017/02/15 Javascript
原生js更改css样式的两种方式
2017/03/15 Javascript
在页面中引入js的两种方法(推荐)
2017/08/29 Javascript
Vuejs 2.0 子组件访问/调用父组件的方法(示例代码)
2018/02/08 Javascript
详解如何在你的Vue项目配置vux
2018/06/04 Javascript
angularJs利用$scope处理升降序的方法
2018/10/08 Javascript
[04:19]完美世界携手游戏风云打造 卡尔工作室模型介绍篇
2013/04/24 DOTA
[01:31:02]TNC vs VG 2019国际邀请赛淘汰赛 胜者组赛BO3 第一场
2019/08/22 DOTA
python监控网卡流量并使用graphite绘图的示例
2014/04/27 Python
简单介绍Python中的JSON使用
2015/04/28 Python
Python实现批量修改文件名实例
2015/07/08 Python
Python语法快速入门指南
2015/10/12 Python
Python 元类实例解析
2018/04/04 Python
Django项目中包含多个应用时对url的配置方法
2018/05/30 Python
Python多线程应用于自动化测试操作示例
2018/12/06 Python
解决项目pycharm能运行,在终端却无法运行的问题
2019/01/19 Python
python将字母转化为数字实例方法
2019/10/04 Python
Python基于Serializer实现字段验证及序列化
2020/11/04 Python
如何利用CSS3制作3D效果文字具体实现样式
2013/05/02 HTML / CSS
Peter Alexander新西兰站:澳大利亚领先的睡衣设计师品牌
2016/12/10 全球购物
Vans(范斯)新西兰官方网站:美国原创极限运动品牌
2020/09/19 全球购物
blueseventy官网:铁人三项和比赛泳衣
2021/02/06 全球购物
网络技术支持面试题
2013/04/22 面试题
小学开学寄语
2014/01/19 职场文书
聚美优品的广告词
2014/03/14 职场文书
导师就业推荐信范文
2014/05/22 职场文书
2015年幼儿园学前班工作总结
2015/05/18 职场文书
2015年评职称个人工作总结
2015/10/15 职场文书
Nginx解决前端访问资源跨域问题的方法详解
2021/03/31 Servers