Django MTV之model
Django ORM
O(objects):类和对象。
R(Relation):关系,关系数据库中的表格。
M(Mapping):映射。
Django ORM框架的功能:
a) 建立模型类和表之间的对应关系,允许我们通过面向对象的方式来操作数据库。
b) 根据设计的模型类生成数据库中的表格。
c) 通过方便的配置就可以进行数据库的切换。
1. Django数据库配置
2.1 mysql命令回顾
登录mysql数据库:mysql –uroot –p
查看有哪些数据库:show databases
创建数据库:create database test charset=utf8; #切记:指定编码
使用数据库:use test;
查看数据库中的表:show tables;
2.2 Django配置使用mysql数据库
修改settings.py中的DATABASES。
注意:django框架不会自动帮我们生成mysql数据库,所以我们需要自己去创建(也就是说只能生成表)。
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'test', 'USER': 'root', 'PASSWORD':'ROOT', 'HOST':'', # 空代表连接本机 'PORT': 3306 , } }
2.3 切换mysql数据库之后不能启动服务器
需要安装操作mysql数据库的包,python2环境和python3环境有以下区别。
a) python2需要安装mysql-python:
pip install mysql-python
b) python3需要安装pymysql:
pip install pymysql
python3中安装好pymysql,需要在test/__init__.py中加如下内容:
import pymysql pymysql.install_as_MySQLdb()
2.模型类设计
2.1 在应用models.py中设计模型类。
必须继承与models.Model类。
1) 设计BookInfo类。
2) 设计HeroInfo类。
Models.ForeignKey可以建立两个模型类之间一对多的关系,django在生成表的时候,就会在多端的表中创建一列作为外键,建立两个表之间一对多的关系。
#models.py from django.db import models # models.字段类型(约束条件) class Book(models.Model): # 一类 btitle = models.CharField(max_length=10,) bpub_date = models.DateField(default='1990-01-01') class Hero(models.Model): # 多类 hname = models.CharField(max_length=10,) hgender = models.BooleanField(default=False) hskill = models.CharField(max_length=10,) hbook = models.ForeignKey('Book',on_delete=models.CASCADE) # 注意:1.'Book'也可以不加引号,但需要注意,不加引号意思是从变量Book去找对应的多类, # 所以Book类要写在Hero类前面,预加载时才可以正确读取到此变量。 # 2.Django 2.0版本以后,在定义ForeignKey 的时候, # 必须给on_delete字段给值,CASCADE为级联删除,DO_NOTHING是 什么也不干。
2.2 模型类生成表
1) 生成迁移文件
命令:python manage.py makemigrations
迁移文件是根据模型类生成的。
2) 执行迁移生成表
命令:python mange.py migrate
根据迁移文件生成表。
生成表名的默认格式为: 应用名_模型类名小写 ( 此例应用为books )
2.3 通过模型类操作数据表
首先导入模型类:
from book.models import Book,Hero
1) 向books_book表中插入一条数据。
方式一:通过定义一个对象,对对象进行操作。
b = Book() #定义一个BookInfo类的对象 b.btitle ='天龙八部' #定义b对象的属性并赋值 b.bpub_date = '1990-1-1' b.save() #才会将数据保存进数据库
方式二:通过 对象.objects.create(字段1=值1,字段2=值2) 插入一条数据
Book.objects.create(btitle='水浒传',bpub_date='1990-1-1') #
2) 查询出books_book表中id为1的数据。
b = Book.objects.get(id=1)
3) 在上一步的基础上改变b对应图书的出版日期。
b.bpub_date = ‘1989,10,21’
b.save() #才会更新表格中的数据
4) 紧接上一步,删除b对应的图书的数据。
b.delete() #才会删除
5) 向books_hero表中插入一条数据。
h = Hero()
h.hname = '郭靖'
h.hgender = False
h.hcomment = ‘降龙十八掌’
b2 = Book.objects.get(id=2)
h.hbook = b2 #给关系属性赋值,英雄对象所属的图书对象
h.save()
6) 查询图书表里面的所有内容。
BookInfo.objects.all()
HeroInfo.objects.all()
通过模型类.objects属性可以调用如下函数,实现对模型类对应的数据表的查询。
以下函数中,只有get的返回值是一个模型类对象,其他的返回值均为QuerySet类型,
函数名 |
功能 |
返回值 |
说明 |
get |
返回表中满足条件的一条且只能有一条数据。 |
返回值是一个模型类对象。 |
参数中写查询条件。 1) 如果查到多条数据,则抛异常MultipleObjectsReturned。 2)查询不到数据,则抛异常:DoesNotExist。 |
all |
返回模型类对应表格中的所有数据。 |
返回值是QuerySet类型 |
查询集 |
filter |
返回满足条件的数据。 |
返回值是QuerySet类型 |
参数写查询条件。 |
exclude |
返回不满足条件的数据。 |
返回值是QuerySet类型 |
参数写查询条件。 |
order_by |
对查询结果进行排序。 |
返回值是QuerySet类型 |
参数中写根据哪些字段进行排序。 |
2.4 关联操作
books_hero
books_book
关联查询(一对多)
在一对多关系中,一对应的类我们把它叫做一类,多对应的那个类我们把它叫做多类,我们把多类中定义的建立关联的类属性叫做关联属性。
例:查询id为1的图书关联的英雄的信息。
b=Book.objects.get(id=1)
b.hero_set.all()
1)通过模型类查询:
Hero.objects.filter(hbook__id=1)
例:查询id为1的英雄关联的图书信息。
h = Hero.objects.get(id=1)
h.hbook
Book.objects.filter(hero__id=1)
格式:
由一类的对象查询多类的时候: hero_obj = Book.objects.get(id=1).hero_set.all()
一类的对象.多类名小写_set.all() #查询所有所对应的多类数据
由多类的对象查询一类的时候: book_obj = Hero.objects.get(id=1).hbook
多类的对象.关联属性 #查询多类的对象对应的一类的对象
通过双下划线实现由多类的对象查询一类对象的时候: Hero.objects.filter(hbook_id=1)
多类的对象. objects.filter(关联属性_id=值)
2)通过模型类实现关联查询
例:查询图书信息,要求图书关联的英雄的技能包含'天'。
Book.objects.filter(hero__hskill__contains='天')
例:查询图书信息,要求图书中的英雄的id大于3.
Book.objects.filter(hero__id__gt=3)
例:查询书名为“天龙八部”的所有英雄。
Hero.objects.filter(hbook__btitle='天龙八部')
通过多类的条件查询一类的数据:
一类名.objects.filter(多类名小写__多类属性名__条件名)
通过一类的条件查询多类的数据:
多类名.objects.filter(关联属性__一类属性名__条件名)
条件名:
__lt 小于 __gt 大于 __contains 包含
注:为帮助理解记忆,此出的第一个双下划线可以简单的理解为 对象.属性 中的 .
3).插入、更新和删除
调用一个模型类对象的save方法的时候就可以实现对模型类对应数据表的插入和更新。
调用一个模型类对象的delete方法的时候就可以实现对模型类对应数据表的数据删除。
4)QuerySet的values和values_list
在通过模型类对象查询之后所得到的查询集QuerySet
例如:查找天龙八部所对应的英雄
queryset = Hero.objects.filter(hbook__btitle='天龙八部') print(queryset.values()) #values(*field) values的参数可以填写你所需要的字段 输出: <QuerySet [{'id': 1, 'hname': '虚竹', 'hgender': True, 'hskill': '天山折梅手', 'hbook_id': 1}, {'id': 2, 'hname': '段誉', 'hgender': True, 'hskill': '凌波微步', 'hbook_id': 1}, {'id': 3, 'hname': '乔峰', 'hgender': True, 'hskill': '降龙十八掌 ', 'hbook_id': 1}]> # queryset.values 输出是包含一个字典集合 print(book_obj.values_list()) 输出:<QuerySet [(1, '虚竹', True, '天山折梅手', 1), (2, '段誉', True, '凌波微步', 1), (3, '乔峰', True, '降龙十八掌', 1)]> # queryset.values_list() 输出是包含一个元组集合