Python全栈之路系列之Django模型

MTV开发模式

把数据存取逻辑、业务逻辑和表现逻辑组合在一起的概念有时被称为软件架构的Model-View-Controller(MVC)模式。在这个模式中,Model代表数据存取层,View代表的是系统中选择显示什么和怎么显示的部分,Controller指的是系统中根据用户输入并视需要访问模型,以决定使用哪个视图的那部分。

Django紧紧地遵循这种MVC模式,可以称得上是一种MVC框架。

以下是Django中M、VC各自的含义:

  1. **M**: 数据存取部分,由django数据库层处理;

  2. **V**: 选择显示哪些数据要显示以及怎样显示的部分,由视图和模板处理;

  3. **C**: 根据用户输入委派视图的部分,由Django框架根据URLconf设置,对给定URL调用适当的Python函数;

C由框架自行处理,而Django里更关注的是模型(Model)模板(Template)视图(Views),Django也被称为MTV框架,在MTV开发模式中:

  1. **M** 代表模型(Model),即数据存取层,该层处理与数据相关的所有事务:如何存取、如何验证有效性、包含哪些行为以及数据之间的关系等;

  2. **T** 代表模板(Template),即表现层,该层处理与表现相关的决定:如何在页面或其他类型文档中进行显示;

  3. **V** 代表视图(View),即业务逻辑层,该层包含存取模型及调取恰当模板的相关逻辑,你可以把它看作模型与模板之间的桥梁;


数据库配置

Django的数据库在settings.py文件中配置,打开这个文件找到DATABASES字段进行数据库的配置:

DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'mydatabase','USER': 'root','PASSWORD': 'as','HOST': '127.0.0.1','PORT': '3306',}
}

以下是一个MySQL数据库的配置属性:

字段 描述
ENGINE 使用的数据库引擎
NAME 数据库名称
USER 那个用户连接数据库
PASSWORD 用户的密码
HOST 数据库服务器
PORT 端口

ENGINE字段所支持的内置数据库

  1. django.db.backends.postgresql

  2. django.db.backends.mysql

  3. django.db.backends.sqlite3

  4. django.db.backends.oracle

无论你选择使用那个数据库都必须安装此数据库的驱动,即python操作数据库的介质,在这里你需要注意的是python3.x并不支持使用MySQLdb模块,但是你可以通过pymysql来替代mysqldb,首先你需要安装pymysql模块:

pip3 install pymysql

然后再项目的__init__.py文件加入以下两行配置:

import pymysql
pymysql.install_as_MySQLdb()

当数据库配置完成之后,我们可以使用python manage.py shell进入项目测试,输入下面这些指令来测试你的数据库配置:

E:\DarkerProjects>python manage.py shell
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:18:55) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.db import connection
>>> cursor = connection.cursor()

如果没有显示什么错误信息,那么你的数据库配置是正确的。

第一个应用程序

让我们来创建一个Django app,一个包含模型,视图和Django代码,并且形式为独立Python包的完整Django应用。

Projectapp之间的不同就是一个是配置另一个是代码

  1. 一个Project包含很多个Django app以及对它们的配置;

  2. 技术上,Project的作用是提供配置文件,比方说哪里定义数据库连接信息, 安装的app列表,TEMPLATE等等;

  3. 一个app是一套Django功能的集合,通常包括模型和视图,按Python的包结构的方式存在;

  4. 例如,Django本身内建有一些app,例如注释系统和自动管理界面,app的一个关键点是它们是很容易移植到其他Project和被多个Project复用。

如果你使用了Django的数据库层(模型),你必须创建一个Django app,模型必须存放在apps中,因此,为了开始建造我们的模型,我们必须创建一个新的app:

E:\DarkerProjects>python manage.py startapp darker

E:\DarkerProjects这是我的项目根目录,创建完成之后会自动创建如下文件:

E:\DarkerProjects>tree /f darker
文件夹 PATH 列表
卷序列号为 0003-4145
E:\DARKERPROJECTS\DARKER
│  admin.py
│  apps.py
│  models.py
│  tests.py
│  views.py
│  __init__.py
│
└─migrations__init__.py

第一个模型

首先我们需要创建三张表,分别是:

  1. 学生表(student),拥有字段: id/sname/gender

  2. 课程表(course),拥有字段: id/cname

  3. 成绩表(score),拥有字段: id/student_id/course_id

打开app的models.py目录输入以下代码:

from django.db import models# Create your models here.class student(models.Model):# 自增主键id = models.AutoFieldsname = models.CharField(max_length=12)gender = models.CharField(max_length=2)class course(models.Model):# 自增主键id = models.AutoFieldcname = models.CharField(max_length=12)class score(models.Model):# 自增主键id = models.AutoField# 设置外键关联student_id = models.ForeignKey(student)course_id = models.ForeignKey(course)

每个数据模型都是django.db.models.Model的子类,它的父类Model包含了所有必要的和数据库交互的方法,并提供了一个简洁漂亮的定义数据库字段的语法,每个模型相当于单个数据库表,每个属性也是这个表中的一个字段,属性名就是字段名;

模型安装

要通过django在数据库中创建这些表,首先我们需要在项目中激活这些模型,将darker app添加到配置文件的已安装应用列表中即可完成此步骤;

编辑settings.py文件,找到INSTALLED_APPS设置,INSTALLED_APPS告诉Django项目哪些app处于激活状态:

INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','darker',
]

通过下面的指令来创建数据表:

# 检查是否正确
E:\DarkerProjects>python manage.py check
System check identified no issues (0 silenced).
# 在数据库中生成表
E:\DarkerProjects>python manage.py makemigrations
Migrations for 'darker':darker\migrations\0002_auto_20160809_1423.py:- Create model course- Create model score- Create model student- Remove field authors from book- Remove field student from book- Delete model Author- Delete model Book- Delete model student- Add field student_id to score
# 生成数据
E:\DarkerProjects>python manage.py migrate
Operations to perform:Apply all migrations: admin, auth, contenttypes, darker, sessions
Running migrations:Rendering model states... DONEApplying contenttypes.0001_initial... OKApplying auth.0001_initial... OKApplying admin.0001_initial... OKApplying admin.0002_logentry_remove_auto_add... OKApplying contenttypes.0002_remove_content_type_name... OKApplying auth.0002_alter_permission_name_max_length... OKApplying auth.0003_alter_user_email_max_length... OKApplying auth.0004_alter_user_username_opts... OKApplying auth.0005_alter_user_last_login_null... OKApplying auth.0006_require_contenttypes_0002... OKApplying auth.0007_alter_validators_add_error_messages... OKApplying auth.0008_alter_user_username_max_length... OKApplying darker.0001_initial... OKApplying darker.0002_auto_20160809_1423... OKApplying sessions.0001_initial... OK

django1.7之前的版本都是:

python manage.py syncdb

django1.7及之后的版本做了修改,把1步拆成了2步,变成:

python manage.py makemigrations
python manage.py migrate

查看创建的数据表:

mysql> show tables;
+----------------------------+
| Tables_in_mydb             |
+----------------------------+
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| darker_course              |
| darker_score               |
| darker_student             |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
+----------------------------+
13 rows in set (0.00 sec)

基本数据访问

运行python manage.py shell并使用Django提供的高级Python API

E:\DarkerProjects>python manage.py shell
# 导入student模型类,通过这个类我们可以与student数据表进行交互
>>> from darker.models import student# 创建一个student类的实例并设置了字段sname, gender的值
>>> s1 = student(sname="ansheng", gender="男")# 调用该对象的save()方法,将对象保存到数据库中,Django会在后台执行一条INSERT语句
>>> s1.save()# 在插入一条数据
>>> s2 = student(sname="as", gender="女")
>>> s2.save()# 使用student.objects属性从数据库取出student表的记录集,这个属性有许多方法,student.objects.all()方法获取数据库中student类的所有对象,实际上Django执行了一条SQL SELECT语句>>> student_list = student.objects.all()
>>> student_list
<QuerySet [<student: student object>, <student: student object>]>

让获取到的数据显示为字符串格式

我们可以简单解决这个问题,只需要在上面的三个表类中添加一个方法__str__,如下:

from django.db import models# Create your models here.class student(models.Model):id = models.AutoFieldsname = models.CharField(max_length=12)gender = models.CharField(max_length=2)def __str__(self):return self.snameclass course(models.Model):id = models.AutoFieldcname = models.CharField(max_length=12)def __str__(self):return self.cnameclass score(models.Model):id = models.AutoFieldstudent_id = models.ForeignKey(student)course_id = models.ForeignKey(course)

然后ctrl+c推出shell重新进入

E:\DarkerProjects>python manage.py shell
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:18:55) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from darker.models import student
>>> student_list = student.objects.all()
>>> student_list
# 这次获取的就是字符串而不是对象了
<QuerySet [<student: ansheng>, <student: as>]>

插入和更新数据

插入数据

>>> s1 = student(sname="安生", gender="男")

将数据保存到数据库

>>> s1.save()

获取刚插入的记录主键id

>>> s1.id
3

修改数据内容

>>> s1.gender="女"
>>> s1.save()

相当于执行了下面的SQL指令

UPDATE darker_student SET gender = '女' WHERE id=3;

选择对象

下面的指令是从数据库中获取所有的数据:

>>> student.objects.all()
<QuerySet [<student: ansheng>, <student: as>, <student: 安生>]>

Django在选择所有数据时并没有使用SELECT*,而是显式列出了所有字段,SELECT *会更慢,而且最重要的是列出所有字段遵循了Python界的一个信条:明言胜于暗示

数据过滤

使用filter()方法对数据进行过滤

>>> student.objects.filter(sname="安生", gender="女")
<QuerySet [<student: 安生>]>

snamecontains之间有双下划线,gender部分会被Django翻译成LIKE语句:

>>> student.objects.filter(sname__contains="a")
<QuerySet [<student: ansheng>, <student: as>]>

翻译成下面的SQL

SELECT id, sname, gender FROM darker_student WHERE name LIKE '%a%';

获取单个对象

>>> student.objects.get(sname="as")
<student: as>

数据排序

使用order_by()这个方法进行排序

>>> student.objects.order_by("sname")
<QuerySet [<student: ansheng>, <student: as>, <student: 安生>]>

如果需要以多个字段为标准进行排序(第二个字段会在第一个字段的值相同的情况下被使用到),使用多个参数就可以了,如下:

>>> student.objects.order_by("sname", "gender")
<QuerySet [<student: ansheng>, <student: as>, <student: 安生>]>

我们还可以指定逆向排序,在前面加一个减号 - 前缀:

>>> student.objects.order_by("-sname")
<QuerySet [<student: 安生>, <student: as>, <student: ansheng>]>

设置数据的默认排序

如果你设置了这个选项,那么除非你检索时特意额外地使用了order_by(),否则,当你使用Django的数据库API去检索时,student对象的相关返回值默认地都会按sname字段排序。

class student(models.Model):id = models.AutoFieldsname = models.CharField(max_length=12)gender = models.CharField(max_length=2)def __str__(self):return self.snameclass Meta:ordering = ['sname']

连锁查询

>>> student.objects.filter(id="2").order_by("-sname")
<QuerySet [<student: as>]>

限制返回的数据

>>> student.objects.order_by('sname')[0]
<student: ansheng>
>>> student.objects.order_by('sname')[1]
<student: as>

类似的,你可以用Python的列表切片来获取数据:

>>> student.objects.order_by('sname')[0:2]
<QuerySet [<student: ansheng>, <student: as>]>

虽然不支持负索引,但是我们可以使用其他的方法,比如,稍微修改order_by()语句来实现:

>>> student.objects.order_by('-sname')[0]
<student: 安生>

更新多个对象

更改某一指定的列,我们可以调用结果集(QuerySet)对象的update()方法:

>>> student.objects.filter(id=2).update(sname='Hello')
1

update()方法对于任何结果集(QuerySet)均有效,这意味着你可以同时更新多条记录,一下实例将所有的性别都改成女:

>>> student.objects.all().update(gender='女')
3

update()方法会返回一个整型数值,表示受影响的记录条数

删除对象

删除数据库中的对象只需调用该对象的delete()方法。

删除指定数据

>>> student.objects.all().filter(sname="ansheng").delete();
(1, {'darker.student': 1, 'darker.score': 0})
>>> student.objects.all()
<QuerySet [<student: Hello>, <student: hello>, <student: 安生>]>

删除所有数据

>>> student.objects.all().delete()
(3, {'darker.student': 3, 'darker.score': 0})
>>> student.objects.all()
<QuerySet []>

字段属性

属性 描述
models.AutoField 自增列,默认会生成一个id列,如果要显示的自定义一个自增列,必须将给列设置为主键primary_key=True
models.CharField 字符串字段,必须有max_length参数
models.BooleanField 布尔类型,不能为空,Blank=True
models.ComaSeparatedIntegerField 用逗号分割的数字,必须有max_lenght参数
models.DateField 日期类型,对于参数,auto_now = True则每次更新都会更新这个时间;auto_now_add则只是第一次创建添加,之后的更新不再改变
models.DateTimeField 日期类型datetimeDateField的参数
models.Decimal 十进制小数类型,必须指定整数位max_digits和小数位decimal_places
models.EmailField 字符串类型(正则表达式邮箱)
models.FloatField 浮点类型
models.IntegerField ×××
models.BigIntegerField 长×××
models.IPAddressField 字符串类型(ip4正则表达式)
models.GenericIPAddressField 字符串类型(ip4和ip6是可选的),参数protocol可以是:both、ipv4、ipv6,验证时,会根据设置报错
models.NullBooleanField 允许为空的布尔类型
models.PositiveIntegerFiel 正Integer
models.PositiveSmallIntegerField 正smallInteger
models.SlugField 减号、下划线、字母、数字
models.SmallIntegerField 数字,数据库中的字段有:tinyint、smallint、int、bigint
models.TextField 字符串
models.TimeField 时间
models.URLField 字符串,地址正则表达式
models.BinaryField 二进制
models.ImageField 图片
models.FilePathField 文件

属性所拥有的方法

方法 描述
null=True 数据库中字段是否可以为空
blank=True django的 Admin 中添加数据时是否可允许空值
primary_key = False 主键,对AutoField设置主键后,就会代替原来的自增 id 列
auto_now 自动创建—-无论添加或修改,都是当前操作的时间
auto_now_add 自动创建—-永远是创建时的时间
max_length 最大值
default 默认值
verbose_name Admin中字段的显示名称
name竖线db_column 数据库中的字段名称
unique=True 不允许重复
db_index = True 数据库索引
editable=True 在Admin里是否可编辑
error_messages=None 错误提示
auto_created=False 自动创建
help_text 在Admin中提示帮助信息

连表结构

方法 描述
models.ForeignKey(其他表) 一对多
models.ManyToManyField(其他表) 多对多
models.OneToOneField(其他表) 一对一

#Python全栈之路 #Django

转载于:https://blog.51cto.com/edeny/1925031

4Python全栈之路系列之Django模型相关推荐

  1. 8Python全栈之路系列之Django Cookie 与Sessi

    Python全栈之路系列之Django Cookie与Sessi Cookies cookies是浏览器为Web服务器存储的一小段信息,每次浏览器从某个服务器请求页面时,它向服务器回送之前收到的coo ...

  2. 7Python全栈之路系列之Django表单

    Python全栈之路系列之Django表单 从Request对象中获取数据 HttpRequest对象包含当前请求URL的一些信息: 熟悉/方法 描述 例如 request.path 除域名以外的请求 ...

  3. 4python全栈之路系列之scrapy爬虫s

    python全栈之路系列之scrapy爬虫 An open source and collaborative framework for extracting the data you need fr ...

  4. 1Python全栈之路系列Web框架介绍

    Python全栈之路系列之Web框架介绍 所有的语言Web框架本质其实就是起一个socket服务端,监听一个端口,然后运行起来 Web框架包含两部分,一部分是socket,另外一部分是业务的逻辑处理, ...

  5. 2Python全栈之路系列之基于socket实现聊天机器人

    Python全栈之路系列之基于socket实现聊天机器人 通过socket实现局域网内的聊天工具. service.py文件如下: #!/usr/bin/env python # _*_ coding ...

  6. 2Python全栈之路系列之MysQl基本数据类型

    Python全栈之路系列之MySQL基本数据类型 MySQL中定义数据字段的类型对你数据库的优化是非常重要的. MySQL支持多种类型,大致可以分为三类: 数字类型 日期和时间类型 字符串类型 数字类 ...

  7. 1Python全栈之路系列之MySQL数据库基本操作

    Python全栈之路系列之MySQL数据库基本操作 MySQL数据库介绍 MySQL是一种快速易用的关系型数据库管理系统(RDBMS),很多企业都在使用它来构建自己的数据库. MySQL由一家瑞典公司 ...

  8. 5Python全栈之路系列之字符串格式化

    Python全栈之路系列之字符串格式化 This PEP proposes a new system for built-in string formatting operations, intend ...

  9. Python全栈之路系列之数字数据类型

    上篇文章中我们简单的体验了Python语言基本概念与语法,那么在继续深入下去的过程中,不妨先学习几个常见的Python内置数据类型?这也是大部分Python教科书的学习目录,由浅至深,慢慢深入. Py ...

最新文章

  1. 自定义字段类型的开发[转]
  2. iOS开发之详解正则表达式
  3. cloudstack centOS安装(一)
  4. java communiframe_[Java教程]javascript iframe相关操作
  5. ZOJ 1610 Count the Colors
  6. impala的substr从第几位截到最后一位_冰雪奇缘2彩蛋:片名内含深意,艾莎是第13位公主象征着背叛...
  7. ListMapString,Object之按照某个字段排序
  8. 安装算量软件价格_鹏业安装算量软件正版购买渠道
  9. 了解了广告行业利益相关方,横扫一切商业模式
  10. USB转RS422/485/232串口线异常问题记录
  11. ios 根据日期知道周几_iOS 计算指定日期是周几星期几
  12. 计算机英语单词怎么读,英语单词read怎么读,read的音标是什么,read是什么意思 - 音标网...
  13. 《决胜B端》读书笔记04:互联网领域常见产品方向、盈利模式、盈利模式对产品方向的诉求
  14. len是python的内置函数吗_len(x) 击败 x.len(),从内置函数看 Python 的设计思想(内有公号宣传,不喜勿进)...
  15. 【数据可视化笔记】如何选择图表?
  16. 格式化GridView 数字0和1转换为男女 及更复杂的处理
  17. 4阶显式Runge-Kutta法解常微分方程的通用程序--python实现
  18. spark错误ERROR LiveListenerBus: SparkListenerBus has already stopped!
  19. 交换机链路聚合在网络中的作用
  20. 深度解读BN、LN、WN、CN

热门文章

  1. oracle11g程序调优纪实
  2. 网站静态文件缓存的处理
  3. Java and Python: a perfect couple - Developer.com
  4. Javascript 滑动效果菜单 TreeView [Javascript]
  5. 微软对学生免费提供Visual Studio等开发软件(包括中国)
  6. SQLServer之创建分布式事务
  7. RN中布局样式的写法
  8. tomcat8 安装部署--一键版本
  9. 润乾V5部署url应用名为空applet无法打印解决方案
  10. android升级gradle到3.4.1