Django数据库
一、Django中的App
App(application)就是应用的意思,当项目足够大的时候,我们将功能单独分成多个App进行开发
举个例子:一个项目Project就相当于某某大学,一个应用App就相当于某某学院
Project(项目)和Application(应用)的关系:
一个Project(项目)是一系列 Django App(应用)的实例,外加那些应用的配置。例如定义数据库连接信息、安装的应用列表、DIRS,等等
一个App(应用)是一系列便携的 Django 功能,通常包含模型和视图。打包在一个 Python 包里。Django 自带了一些应用,例如管理后台。这些应用的独特之处是便携,可以在多个项目中复用
Django本身是鼓励开发者进行相对独立的项目开发的,因此我们建议以后使用App进行开发
(一)创建App
1、命令: python manage.py startapp app名称
2、在 settings.py 文件 INSTALLD_APPS 列表中注册app
二、Django数据库
之前我们学了模板和视图,模板负责显示,视图负责执行逻辑,然后返回响应
对现代的 Web 应用程序而言,视图逻辑经常需要与数据库交互。在数据库驱动型网站中,网站连接数据库服务器,从中检索数据,然后在网页中把数据显示出来。此外,可能还会提供让访客自行填充数据库的方式
Django 非常适合构建数据库驱动型网站,它提供了简单而强大的工具(ORM),易于使用 Python 执行数据库查询
-
ORM介绍
Object Relational Mapping,简称ORM(对象关系映射)将面向对象语言程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式(对象)转换到另外一种形式(数据库表格)
通过ORM怎样进行转换的呢?
Python中的一个类对应对应数据库中的一张表格
Python中的一个对象对应表格中的一条记录
Python中的类的属性 对应 表格中的字段
ORM优势:
ORM提供了对数据库的映射,不用直接编写SQL代码,只需像操作对象一样从数据库操作数据。让软件开发人员专注于业务逻辑的处理,提高了开发效率
ORM劣势:
ORM的缺点是会在一定程度上牺牲程序的执行效率
-
Django建模
Django的数据库模型,必须要在App当中的models中创建。
定义数据库模型
实体类必须继承models.Model-
自动设置主键
id = models.AutoField(primary_key=True)
-
-
数据库配置
https://docs.djangoproject.com/zh-hans/2.1/ref/settings/#std:setting-DATABASES
1、配置MySQL数据库
DATABASES = { ‘default‘: { ‘ENGINE‘: ‘django.db.backends.mysql‘, # 连接的数据库 ‘NAME‘: ‘dailyfresh‘, # 数据库的库名字 ‘USER‘: ‘root‘, # 数据库用户名 ‘PASSWORD‘: ‘mysql‘, # 数据库的密码 ‘HOST‘: ‘127.0.0.1‘, ‘PORT‘: ‘3306‘, # 端口 } }
2、下载pymysql模块
pip install pymysql在项目__ init __ 文件下加上
Import pymysql
pymysql.install_as_MySQLdb()注意:Python2 版本中使用的是MySQLdb的模块,现在用的是Python3版本,由 PyMySQL取代
(3)排错:Django2.2.1 和 PyMySQL 不兼容,需要修改源码
? 3、数据迁移
? 在Django 的ORM操作当中,数据库操作需要进行命令同步
? python manage.py check 检测数据库配置是否有错误
? 1、检查
? python manage.py check
? 2、生成映射文件
? python manage.py makemigrations
? 3、迁移到数据库中
? python manage.py migrate
? 数据库表默认的名字是:app名_实体类名
-
修改数据库名字
# 打印字段名 def __str__(self): return ‘<obj name:{}>‘.format(self.name) # 修改数据库表名 class Meta: db_table = "seller"
-
Django模型常用的字段
字段的名称 字段描述 CharField 字符串类型,必须设置max_length IntergerField 整数类型 FloatField 小数类型 EmailField 邮件格式的字符串 TextField 文本类型 DateField 日期 年月日 DateTimeField 时间 年月日时分秒 FileField 文件类型 特殊类型,可以保存文件路径同时自动上传文件 必须设置upload_to上传到媒体路径下的位置 ImageField 图片文件类型 特殊类型,可以保存文件路径同时自动上传文件 ImageField因为需要保存图片,所以需要配置
(1) 安装pillow模块
? pip install pillow
(2) 配置媒体文件
? 在配置文件settings中最后一行增加
? MEDIA_ROOT = os.path.join(BASE_DIR,"static")
-
Django常用的字段参数
参数名称 参数描述 verbose_name 别名,在后台可以使用 unique 不可以重复 blank 可以为空,常用于字符串 null 可以为null,常用于数字,和时间 max_length 字符类似的长度 upload_to 文件上传地址 Auto_now 默认当前时间 总结:
(1)Django ORM默认自带id主键
(2)Django ORM默认字段不为空,为了方便,通常可以把blank和null都设置
四、Django ORM 单表操作
django 可以通过命令开启命令行模式对模型进行操作
安装ipython:pip install ipython
进入ipython命令:python manage.py shell
1、新增
(1)通过实体类的save()
seller = Seller()
seller.name="lanwang"
seller.age = 22
seller.password = "123"
seller.save()
(2) 通过实体类.object.create(),这个方法创建对象并返回此对象
Seller.objects.create(
name = "小王",
age=22,
password = "123"
)
2、删除操作
seller = Seller.objects.get(pk=11)
seller.delete()
3、修改
seller = Seller.objects.get(pk=12)
seller.name = "赵云"
seller.save()
4、查询
(1) get方法,返回与所给筛选条件相匹配的对象
返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误
返回具体的某个模型类的对象,而不是QuerySet列表对象
seller = Seller.objects.get(id=12)
(2) filter方法 返回包含了与所给筛选条件相匹配的对象,返回 QuerySet 列表对象。获取对象时,通过索引或者遍历可以传入多个关键字,底层的sql 使用and 来连接多个条件
Seller.objects.filter(age__gt=20,gender="男")
(3) all方法
返回 QuerySet 列表对象。获取对象时,通过索引或者遍历
Seller.objects.all()
(4) order_by方法
对查询结果排序
# 逆序
Seller.objects.filter(gender="男").order_by("-age")
# 正序
Seller.objects.filter(gender="男").order_by("age")
(5)first 方法
返回第一条记录
返回具体的某个模型类的对象,而不是QuerySet列表对象
Seller.objects.filter(age__gt=20).first()
(6)last 方法:返回最后一条记录
返回具体的某个模型类的对象,而不是QuerySet列表对象
Seller.objects.filter(age__gt=20).last()
双下划线查询
条件 | 描述 | 举例 |
---|---|---|
__gt | 大于 | StoreUser.objects.filter(id__gt=4) |
__lt | 小于 | StoreUser.objects.filter(id__lt=2) |
__gte | 大等于 | StoreUser.objects.filter(id__gte=2) |
__lte | 小等于 | StoreUser.objects.filter(id__lte=2) |
__contains | 模糊查询 相当于sql like(%keywords%) | StoreUser.objects.filter(phone__contains=‘153‘) |
__in | 判断在范围 | StoreUser.objects.filter(id__in=[1,2,3]) |
__isnull | 判断为空 | StoreUser.objects.filter(phone__isnull=False) |
__startswith | 获取以指定内容开头的记录 | StoreUser.objects.filter(phone__startswith=‘13‘) |
(7)聚合查询: MySQL 中 max min sum avg count
? 导包 from django.db.models import Sum,Avg,Max,Min,Count
? 依赖: aggregate 是Django ORM中的终止语句
? 统计一下性别是男的个数,可以使用进行计算
from django.db.models import *
len(Seller.objects.filter(gender="男"))
Seller.objects.filter(gender="男").aggregate(Count("id"))
(8)分组查询
统计性别人数
Seller.objects.all().values("gender").annotate(Count("id"))
(9) F查询
目前所举的例子在过滤器中都是比较模型字段的值和常量。那么,如果想比较同一个模型中的两个字段的值呢?
为此,Django 提供了F表达式。在查询中,F()的实例引用一个模型字段。在查询过滤器中可以使用这样的引用,以便比较同一个模型实例中的两个字段。
案例:F查询id大于年龄的用户
Seller.objects.filter(pk__gt=F("age"))
(10)Q查询
filter() 等的关键字参数指定的条件是并联在一起的,如果需要执行更复杂的查询(例如,使用or语句查询),可以使用 Q 对象
查询性别是男或者年龄大于20
Seller.objects.filter(Q(age__gt=20)|Q(gender="男"))
Seller.objects.filter(Q(age__gt=20)&Q(gender="男"))
Seller.objects.filter(~Q(gender="男"))
符号 | 描述 |
---|---|
| | 或 or |
& | 且 and |
~ | 非 not、分页 |
(10)分页:Django本身有携带分页函数,可以自动分页,但是也有限制查的方法,使用索引,因为Django
ORM查询的结果集是一个QueryList(类列表对象),所以可以用索引
Seller.objects.order_by("id")[1:4]
五、Django关系操作
在进行数据库建模的时候,开发者需要考虑的除了业务主体携带的字段以外,还需要考虑业务主体间的关系,在Django当中,我们强调下面的三种关系
一、一对一 OneToOneField
外键实体类将外键属性变成OneToOneField,那么主键实体类默认会新增一个属性,名字是外键实体类名字小写
店铺和卖家是一对一
字段参数 | 描述 |
---|---|
to | 设置要关联的表 |
to_field | 设置要关联的字段 |
on_delete | 指的的是如果删除用户店铺该如何处理models.CASCADE 级联删除,删除用户,删除店铺 |
1、增加
seller = Seller.objects.create(name="老王",password="123")
store = Store.objects.create(name="1星店",seller=seller)
2、删除
删除卖家
seller = Seller.objects.get(id=10)
seller.delete()
3、修改
将id是1的店铺转给id是13卖家
先从外键出发
store = Store.objects.get(id=1)
seller = Seller.objects.get(id=13)
store.seller = seller
store.save()
4、查询
seller = Seller.objects.get(id=13)
seller.store
store = Store.objects.get(id=1)
store.seller
store.seller_id
store.seller.id
二、一对多
使用Foreign Key,在一方(GoodsType)会自动增加一个属性goods_set
商品,商品类型,一个类型可以有多种商品,一个商品属于一个类型
1、增加
在商品类型3下新增一个商品
goodstype =Goodstype.objects.get(id=3)
store = Store.objects.get(id=1)
goods = Goods.objects.create(name="老干妈",goodstype=goodstype,store=store)
2、删除
删除商品类型3
goodstype = GoodsType.objects.get(id=3)
goodstype.delete()
3、修改
将id是3的商品的类型改为2类型
goodstype = Goodstype.objects.get(id=2)
goods = Goods.objects.get(id=3)
goods.goodstype = goodstype
goods.save()
4、查询
goodstype =Goodstype.objects.get(id=3)
goodstype = good_set.all()
二、多对多
使用ManyToMany
店铺和商品类型多对多
任选1方(Store)加ManyToMany,会在另一方(GoodsType)自动增加一个属性store_set
foreign key 和manytomany 集合属性,有add新增,remove移除,clear清除,all()查所有返回QuerySet,还有其他的,使用dir查看。
1、增加
新增一个商品类型,增加到店铺1中
goodstype = GoodsType.objects.create(name="五金件")
store = Store.objects.get(id=1)
Store.goodstypes.add(goodstype)
store.save()
2、删除
删店铺类型1
store.delete()
3、修改
店铺2新增商品类型2,商品2去除商品类型1
store = Store.objects.get(id=2)
goodstype = GoodsType.objects.get(id=2)
store.goodstype.add(goodstype)
store,save()
goodstype1 =GoodsType.objects.get(id=1)
store.goodstype.remove(goodstype1)
store.save()
4、查询
店铺2下的商品类型
store = Store.objects.git(id=2)
store = Store.objects.all()
六、MVC和MVT架构模式
1、MVC架构模式
MVC全称Model View Controller,分为三个基本部分:模型Model、视图View和控制器Controller
Model,模型,代表数据存取层,和数据库进行交互
V: View ,视图,产生HTML页面,代表的是系统中选择显示什么和怎么显示的部分
C: Controller,控制器, 接收请求,进行处理,与M和V进行交互,返回响应
这是一种设计思想,实现这种思想的框架很多。
python:flask,django,tornado
java:ssh,ssm,pringmvc
2、MVT架构模式
Django框架借鉴了MVC的思想,也分成三个部分来降低各个部分之间的耦合性,不同之处是Django框架分为三部分:Model模型、Template模板、View视图,这就是MVT模型
Model(模型):负责业务对象与数据库的对象(ORM)
View(视图):负责业务逻辑,并在适当的时候调用Model和Template
Template(模版):负责如何把页面展示给用户