Django新手入门(五)——Models详解

在之前的文章中,我们对Django的MTV模式进行了介绍,相信大家对于Models已经有了初步了解。在这篇文章中,我们将深入探索Models,以求深刻理解Django中的数据操作。

数据库

动态网站最重要的部分,毫无疑问非数据库莫属了。把所有数据通过数据库系统维护在一些数据表中,在需要的时候再以条件式查询的方式取出,然后送到网页显示出来,或者通过新增指令存储新的数据记录,或针对特定的数据项进行修改等。由数据库维护所有内容可以提高数据存取的效率,也可以增加网站提供信息的能力。

数据库(Database,简称DB),简单地说就是一个系统组织过的数据格式,通过特定的接口存取的数据集合。存取这些数据内容的系统叫做数据库管理系统(Database Management System,DBMS)。不同的数据库系统有不同的执行程序和操作方法,定义数据的方式也有可能非常不一样。所幸的是,网页服务器所使用的数据库系统大多为关系数据库系统,而它的主流系统为MySQL,因此大部分数据库系统都会和MySQL兼容,包括Django默认的SQLite文件类型数据库也是如此。

典型情况下,网站系统要存取数据库需要先有一个正确的数据库驱动接口,通过此接口才可以使用该数据库(以MySQL为例)接受的查询命令(SQL查询语言),并在使用之前进行数据库的连接工作。数据库系统通常都是以独立的服务程序运行在某一台主机上,所以连接时,除了要指定连接操作用的账号和密码外,也必须指定主机位置的相关信息,大部分情况下网页服务器和数据库系统都位于同一台主机上,所以在指定主机位置时,只要使用localhost就可以了。事实上,数据库系统是可以独立于网络上任何一台主机的,而许多主机供应商也提供了数据库主机的服务。

由于网站中最重要的内容是数据库,因此开始设计网站的第一步不是,马上开始编写程序,而是根据网站的需求先设计数据库,确定数据库的所有细节,并做过正规化步骤之后,才能够开始网站的程序设计。因为数据库的内容如果在开始设计程序时发现不符合实际需求或数据表之间的关系有误,要再回去修改数据里的格式以及结构,往往会造成程序内容极大的变动,会花费更多精力,而且可能会冒出许多不该发生的程序错误,因而不得不慎之又慎。

ORM

ORM(Object Relational Mapper)是一种面向对象的程序设计技术,以对象的方式来看待每一笔数据,可以解决底层数据库兼容性的问题。也就是把数据库的操作方式抽象化为统一在Python中习惯的数据操作方式,如果把这些指令对应到实际每一种数据库的内部操作,就由元数据以及Django内部去处理,开发网站的人员不用去担心这个部分。

Django中的ORM

Model是Django表示数据的模式,以Python的类为基础在models.py中设置数据项与数据格式,基本上每个类对应一个数据库中的数据表。因此,定义每个数据项时,除了数据项名称外,也要定义此项目的格式以及这张表和其他表格相互之间的关系(即数据关联)。定义完毕后,网站的其他程序就可以使用Python语句来操作这些数据内容,不用关心实际使用的SQL指令以及使用的是哪一种数据库。

Django中操作数据库

Django中的Models

定义models.py中的类

简单的定义语言如下:

class Post(models.Model):
	# 字段定义
    title = models.CharField(max_length=200)
    slug = models.CharField(max_length=200)
    body = models.TextField()
    pub_date = models.DateTimeField(default=timezone.now)

	# 其他设置
    class Meta:
        ordering = ('-pub_date',)
	
    def __str__(self):
        return self.title

通过这样一个类,我们就可以定义一张数据库的表,通过对表和字段的一些设置,实现在抽象层面上对数据库结果的操作。

常用数据字段

django\db\models\fields\__init__.py中我们能看到这样一段代码

__all__ = [
    'AutoField', 'BLANK_CHOICE_DASH', 'BigAutoField', 'BigIntegerField',
    'BinaryField', 'BooleanField', 'CharField', 'CommaSeparatedIntegerField',
    'DateField', 'DateTimeField', 'DecimalField', 'DurationField',
    'EmailField', 'Empty', 'Field', 'FieldDoesNotExist', 'FilePathField',
    'FloatField', 'GenericIPAddressField', 'IPAddressField', 'IntegerField',
    'NOT_PROVIDED', 'NullBooleanField', 'PositiveIntegerField',
    'PositiveSmallIntegerField', 'SlugField', 'SmallAutoField',
    'SmallIntegerField', 'TextField', 'TimeField', 'URLField', 'UUIDField',
]

列出了Django中自带的一些数据类型,我们介绍一些常用的:

数据字段参数说明数据内容
BigIntegerField64位的大整数
BooleanField布尔值,只有True/False两种
CharFieldmax_length:指定可接受的字符串长度用来存储较短数据的字符串,通常使用于单行的文字数据
DateFieldauto_now:每次对象被存储时就自动加入当前日期 auto_now_add:只有在对象被创建时才加入当前日期日期格式,可用于datetime.date
DataTimeField同上日期时间格式,对应到datetime.datetime
DecimalFieldmax_digits:可接受的最大位数 decimal_places:在所有位数中,小数占几个位定点小数数值数据,适用于Python的Decimal模块的实例
EmailFieldmax_length:最大字符长度可接受电子邮件地址格式的字段
FloatField浮点数字段
IntegerField整数字段,是通用性最高的整数格式
PostiveIntegerField正整数字段
SlugFieldmax_length:最大字符长度和CharField一样,通常用来作为网址的一部分
TextField长文字格式,一般用在HTML窗体的Textarea输入项目中
URLFieldmax_length:最大字符长度和CharField一样,特别用来记录完整的URL网址

常用设置选项

django\db\models\fields\__init__.py第132行,所有字段类的基类Field的构造函数的形参中我们还能看到这样一段代码:

def __init__(self, verbose_name=None, name=None, primary_key=False,
                 max_length=None, unique=False, blank=False, null=False,
                 db_index=False, rel=None, default=NOT_PROVIDED, editable=True,
                 serialize=True, unique_for_date=None, unique_for_month=None,
                 unique_for_year=None, choices=None, help_text='', db_column=None,
                 db_tablespace=None, auto_created=False, validators=(),
                 error_messages=None):

这段代码描述了字段定义时的一些选项,我们对常用的进行介绍:

选项含义
null此字段是否接受存储空值NULL,默认值是False
blank此字段是否接受存储空白内容,默认值是False
choices以选项的方式(只有固定内容的数据可以选用)作为此字段的候选值
default输入此字段的默认值
help_text字段的求助信息
primary_key把此字段设置为数据表中的主键KEY,默认值为False
unique设置此字段是否为唯一值,默认值为False
db_column在数据库中的字段名
verbose_name在键入此信息时展示的字段名
max_length最大字符长度

常用函数以及修饰词

在views.py中对数据进行操作时常用以下函数或修饰词:

函数及修饰词含义
filter()返回符合指定条件的QuerySet
exclude()返回不符合指定条件的QuerySet
order_by()串接到QuerySet之后,针对某一指定的字段进行排序
all()返回所有的QuerySet
get()获取指定符合条件的唯一元素,如果找不到或有一个以上符合条件,都会产生exception
first()/last()获取第1个和最后1个元素
aggregate()可以用来计算数据项的聚合函数
exists()用来检查是否存在某指令条件的记录,通常附加在filter()后面
update()用来快速更新某些数据记录中的字段内容
delete()删除指定的记录
iexact不区分大小写的条件设置
contains/icontains设置条件为含有某一字符串就符合,如SQL语句中的LIKE和ILIKE
in提供一个列表,只要符合列表中的任何一个值均可
gt/gte/lt/lte大于/大于等于/小于/小于等于

有一些函数(如reverse()、exists())可以串接在另一些函数后面,用于进一步过滤信息,修饰词则是放在参数中,在字段名后面加上两个下划线之后再串接,可以为条件设置增加更多的弹性。

同样是查询数据,使用filter会返回一个列表,而使用get会返回一个唯一的值。如果在设置的条件下找不到任何数据,使用filter就会返回一个空列表,而使用get会产生一个DoesNotExit例外,如果设置的条件有一个以上的元素符合条件,那么get也会产生例外。因此,get通常在明确知道该数据只有一笔的情况下才会使用,而且使用的时候也要以try/exception做好例外处理工作。

其他常用设置

  • models.PROTECT:禁止删除并产生一个Exception(ProtectedError)。
  • models.SET_NULL:把外键设置为Null,但是在规划时此字段要设置为可接受null。
  • models.SET_DEFAULT:把外键设置为默认值,但是在规划时此字段要设有默认值。
  • models.DO_NOTHING:什么事都不做。

在Django中使用数据库系统(以MySQL为例)

在Django中使用数据库的步骤如下:

  • 在开发环境中安装MySQL服务器
  • 安装Python和MySQL之间的连接驱动程序
  • 修改settings.py中的设置,提供MySQL的链接信息

在本地使用MySQL的好处是在开发的时候就可以享受高效率的数据库系统,而且可以充分使用phpMyAdmin观察数据库的现状,需要调整数据库内容的时候也非常方便,坏处是同一台计算机中当前使用中的数据如果想要放到另一台计算机使用时,就要使用导入导出SQL的方式迁移数据,在操作上并不方便。而且,要部署网站的时候,之前输入的数据库也都要重新迁移一次才行。如果直接使用的是网络主机上的MySQL服务器,那么不管在哪一台计算机使用的都是同一个数据库,这样就不会有数据不同步的情况了。

  • 6
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值