Django学习笔记( 未完结)
一、介绍
Djingo官网:www.djangoproject.com
Django中文文档参考网站:yiyibooks.cn
本学习版本为2.2.12
参考学习视频:哔哩哔哩——达内教育
二、Django安装
支持Python的版本: 3.5,3.6, 3.7,3.8
2.1在线安装
安装命令:sudo pip3 install django==2.2.12
- 查看是否安装成功:
**sudo pip3 install freeze|grep -i 'Django'**
2.2创建项目
-
终端创建项目命令:django-admin startproject 【项目名】
-
pycharm创建项目:file–>new projedct–>Django–>配置项目名称和路径–>点击创建
2.3启动服务(测试开发)
- 进入项目文件
- 终端执行:python3 manage.py runserver【这个启动方式下,Django在前台启动服务,默认监听端口为8000】
- 浏览器访问http://127.0.0.1:8000就可以看到django的启动页面[端口号调整python3 manage.py runserver 【端口号】
2.4关闭服务
-
ctrl+c 关闭
-
sudo lsof -i :8000查询出Django的进程id
然后kill -9对应Django进程id
三、项目结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uXqtz2ng-1646282935982)(C:\Users\luck\Desktop\2022-01-15 15-39-07屏幕截图.png)]
-
manage.py [项目管理的子命令]
输入python3 manage.py 可以查看所有命令
-
hsx_dome[项目同名文件夹]
init : Python包初始文件
wsgi.py :web服务网关的配置文件——Django正式启动需要用到
urls.py :项目的主要路由配置——http请求进去Django优先调用该文件
settings.py :项目的配置文件——包含项目启动时需要的配置
3.1公有配置(settings.py 文件)
1、BASE _ DIR
- 用于绑定当前项目的绝对路径(动态计算出来的),所有文件
夹都可以依懒此路径
2、DEBUG
- 用于配置 Django 项目的启动模式,取值:
- True 表示开发环境中使用开发调试模式(用于开发中)
- False 表示当前项目运行在生产环境
3、ALLOWED _Н oSTS
- 设置允许访问到本项目的 host 头值
- []空列表,表示只有请求头中 host 为127.0.0.1, localhost 能访问本项目﹣ DEBUG = True 时有效
- [’*],表示任何请求头的 host 都能访问到当前项目
- ['192.168.1.3,'127.0.0.1]表示只有当前两个 host 头的值能访问当前项目
4、 INSTALLED APPS ﹣指定当前项目中安装的应用列表。 MIDDLEWARE ﹣用于注册中间件
5、TEMPLATES ﹣用于指定模板的配置信息
6、DATABASES ﹣用于指定数据库的配置信息
7、LANGUAGECODE ﹣用于指定语言配置
- 英文:" en - us "
- 中文:" zh - Hans "
3.2自定义配置
-
settings . py 中也可以添加开发人员自定义的配置
-
配置建议:名字尽量个性化﹣以防覆盖掉公有配置
例如:Á LIPAY _ KEY )=’ xXxxxx
-
settings . py 中的所有配置项,都可以按需的在代码中引入
引入方式: from django . conf import settings
3.3 url结构
1、定义﹣即统一资源定位符 Uniform Resource Locator
2、作用﹣用来表示互联网上某个资源的地址
3、URL 的一般语法格式为(注:0代表其中的内容可省略):
protocol 😕/ hostname [: port ]/ path [? query] [# fragment ]
例子:http://tts.tmooc.cn/video/showVideo?menuld=657421& version =AID999# subject
protocol (协议)http://tts.tmooc.cn
- http 通过 HTTP 访问该资源。格式 http 😕/
- https 通过安全的 HTTPS 访问该资源。格式 https 😕/
- fle 资源是本地计算机上的文件。格式: file :/1/
hostname (主机名)http://tts.tmooc.cn
- 是指存放资源的服务器的域名系统( DNS )主机名、域名或 IP 地址
port (端口号)http://tts.tmooc.cn:80
- 整数,可选,省略时使用方案的默认端口
- 各种传输协议都有默认的端口号,如 http 的默认端口为80
path (路由地址)http://tts.tmooc.cn/video/showVideo
- 由零或多个"”符号隔开的字符串,一般用来表示主机上的一个目录或文件地址。路由地址决定了服务器端如何处理这个请求
query (查询)****/ video/showVideo?menuld=657421&version=AlD999
- 可选,用于给动态网页传递参数,可有多个参数,用“&”符号隔开,每个参数的名和值用“="符号隔开。
fragment (信息片断) version =AID999# subject
- 字符串,用于指定网络资源中的片断。例如一个网页中有多个名词解释,可使用 fragment 直接定位到某一名词解释。
3.4 处理URL请求
- 浏览器地址栏﹣>http://127.0.0.1:8000/page/2003)
-
Django从配置文件中根据 ROOT URLCONF 找到主路由文件;
默认情况下,该文件在项目同名目录下的urls ;
-
Django 加载主路由文件中的 urlpatterns 变量[包含很多路由的数组]
-
依次匹配 urlpatterns 中的 path ,匹配到第一个合适的中断后续匹配
-
匹配成功﹣调用对应的视图函数处理请求,返回响应
-
匹配失败﹣返回404响应
3.5 视图函数
-
视图函数是用于接收一个浏览器请求( HttpRequest 对象)并通过 HttpResponse 对象返回响应的函数。此函数可以接收浏览器请求并根据业务逻辑返回相应的响应内容给浏览器
-
语法
def xxx _ view ( request [,其它参数…]):
return HttpResponse 对象
四、路由配置1
4.1 path()函数
-
导入:
from django.urls import path
-
语法:
path(route,views,name=None)
-
参数:
route | 字符串类型,匹配的请求路径 |
---|---|
views | 指定路径所对应的视图处理函数的名称 |
name | 为地址起别名,在模板中地址反向解析时使用 |
4.2 path转换器
- 语法:
<转换类型:自定义名>
- 作用:若转换器类型匹配到对应的数据类型,则将数据按照关键字传参的方式传递给视图函数
- 例子:
path('page/<int:page>',views.xxxx)
转换器类型 | 作用 | 样例 |
---|---|---|
str | 匹配除"/"之外的非空字符串 | "v1/users/< str : username> " 匹配 "/v1/users/ guoxiaonaol " |
int | 匹配0或任何正整数 | 返回一个 " page /< int : page >"匹配 / page /100 |
slug | 匹配任意由 ASCIl 字母或数字以及连字符和下划线组成的短标签 | " detail /< slug : sl >"匹配 / detail / this - is - django |
path | 匹配非空字段,包括路径分隔符 | "v1/users/< path : ph >" 匹配/v1/goods/ a / b / c |
4.3 re_path()函数
-
作用:在url的匹配过程中可以使用正则表达式进行精确匹配
-
导入:
from django.urls import path
-
语法:
-
re_path(reg,views,name=None)
-
正则表达式为命名分组模式(?P<name>pattern);匹配提取参数后用关键字传参方式传递给视图函数
五、请求与响应
5.1 定义
- 请求是指浏览器端通过HTTP协议发送给服务器端的数据
- 响应是指服务器端接收到请求后做相应的处理后再回复给浏览器端的数据
5.2 请求方法
方法 | 描述 |
---|---|
get | 请求指定的页面信息,并返回实体主体 |
head | 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头 |
post | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。post请求可能会导致新的资源的建立和/或已有资源的修改 |
put | 从客户端向服务器传送的数据取代指定的文档的内容 |
delete | 请求服务器删除指定的页面 |
connect | HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器 |
option | 允许客户端查看服务器的性能 |
trace | 回显服务器收到的请求,用于测试或诊断 |
5.3 Django的请求
- path_info:URL字符串
- method:字符串,表示HTTP的请求方法,常用值:‘GET’、‘POST’
- GET:QueryDict查询字典的对象,包含get请求方式的所有数据
- POST:QueryDict查询字典的对象,包含post请求方式的所有数据
- FILES:类似于字典的对象,包含所有的上传文件信息
- COOKIES:Python字典,包含所有的cookie,键和值都为字符串
- session:似于字典的对象,表示当前的会话
- boby:字符串,请求体的内容(POST或PUT)
- scheme:请求协议(‘http’/‘https’)
- request.get_full_path():请求的完整路径
- request.META :请求中的元数据(消息头)
- request.META[‘REMOTE_ADDR’]:客户端ip地址
5.4 响应状态码
- 200 ——请求成功
- 301 ——永久重定向-资源(网页等)被永久转移到其他URL
- 302 ——临时重定向
- 404 ——请求的资源(网页等)不存在
- 500 ——内部服务器错误
5.5 响应对象
格式:
HttpResponse(content =响应体 Content_Type =响应体数据类型 status=状态码)
Content_Type:
- text / html (默认的, htmI 文件)
- text / plain (纯文本)
- text / css ( css 文件)
- text / javascript ( js 文件)
- multipart / form - data (文件提交)
- application / json ( json 传输)
- application / xml ( xml文件)
HttpResponse 子类
类型 | 作用 | 状态码 |
---|---|---|
HttpResponseRedirect | 重定向 | 302 |
HttpResponseNotModified | 未修改 | 304 |
HttpResponseBadRequest | 错误请求 | 400 |
HttpResponseNotFound | 没有对应的资源 | 404 |
HttpResponseForbidden | 请求被禁止 | 403 |
HttpResponseServerError | 服务器错误 | 500 |
六、 GET请求和POST请求
6.1 定义:
-
无论是GET还是POST,统一都有视图函数接收请求,通过判断request.method区分具体的请求动作
-
样例
if request.method=='GET': #处理GET请求的业务逻辑 elif request.method=='POST': #处理POST请求的业务逻辑 else:、 #处理其他请求的业务逻辑
6.2 GET处理
GET请求动作,一般用于向服务器获取数据
产生GET请求的场景:
- 浏览器输入url,回车后
- 点击超链接,
- form表单中的method为get
GET请求方式中,如果有数据需要传递给服务器,通常会用查询字符串(Query String)传递
- 在URL地址的?后接的键值对的数据:xxxx?参数=值&参数=值
- 服务器端接收参数:获取客户端请求GET请求提交的数据
方法示例:
request.GET['键']#直接获取URL地址存在键的值
request.GET.get('键','默认值')#直接获取URL地址存在键的值,也可获取URL地址上不存在键,并赋默认值给他
requset.GET.getlist('键')
6.3 POST处理
- POST请求动作:一般用于向服务器提交大量/隐私数据
- 客户端通过表单等POST请求将数据传递给服务器:
<form method='post' action="/login/">
姓名:<input type="text" name="username">
<input type='submit' value='登录'>
</form>
- **服务器端接收参数:**通过判断request.method是否为POST请求:
if request.method=='POST':
#处理POST请求的数据及响应
else:
#处理其他请求的数据及响应
- 使用POST方式接收客户端数据:
request.POST['键']#直接获取URL地址存在键的值
request.POST.get('键','默认值')#直接获取URL地址存在键的值,也可获取URL地址上不存在键,并赋默认值给他
requset.POST.getlist('键')
-
注意:取消csrf验证,否则Django将会拒绝客户端发来的POST请求,报403响应
取消csrf验证:禁止掉settings.py中MIDDLEWARE中的CsrfViewsMiddleWare的中间件
MIDDLEWARE = [ ..... #'django.middleware.csrf.CsrfViewMiddleware', ..... ]
七、Django设计模式及模板层
7.1 传统的MVC模式
MVC代表Model-View-Controller(模型-视图-控制器)模式
- M,主要用于数据层的封装
- V,用于向用户展示结果
- C,用于处理请求、获取数据、返回结果
作用:降低模块间的耦合度
7.2 Django的MTV模式
MTV代表Model-Template-View(模型-模板-视图)模式
- M:负责与数据库交互
- T:负责呈现内容到浏览器
- V :负责接收请求、获取数据、返回结果
作用:降低模块间的耦合度
7.3 模板层
- 模板是可以根据字典数据动态变化的html网页
- 模板可以根据视图中传递的字典数据动态生成相应的html网页
7.4 模板配置
-
创建模板文件夹<项目名>/templates
-
在setting.py中TEMPLATES配置项
BACKEND:指定模板的引擎
DIRS:模板的搜索目录(可以是一个或者多个)
APP_DIRS:是否要在应用中的templates文件夹中搜索模板文件
OPTIONS:有关模板的选项
-
配置中需要修改的部分:
'DIRS': [os.path.join(BASE_DIR,'templates')],
7.5 模板的加载方式
方法一
通过loader获取模板,通过HttpResponse进行响应
在视图函数中
from django.template import loader
#1、通过loader加载模板
t=loader.get_template('模板文件名')
#2、将t转换为HTML字符串
html=t.render(字典数据)
#3、用响应对象将转换的字符串内容返回给浏览器
return HttpResponse(html)
方法二
使用render()直接加载并响应模板
在试图函数中
from django.shortcuts import render
return render(request.'模板文件名',字典数据)
7.6 视图层与模板层之间的交互
-
视图函数中可以将Python变量封装到字典中传递到模板
def xxx_view(request):` dic={` `"变量1":"值1",` `"变量2":"值2"` }` return render(request.'模板文件名',dic)`
-
模板中,我们可以用{{变量名}}的语法调用视图传进来的变量
八、模板层的变量与标签
8.1 模板的变量
-
能传递到模板中的数据类型:
字符串、整型、数组、元组、字典、方法、类实例化对象
-
在模板中使用变量语法:
{{变量名.index}}获取索引对应的值
{{变量名.key}}获取字典对应的值
{{对象.方法}}可以直接调用对象的方法
{{函数名}}可以调用函数
8.2 模板的标签
-
作用:将一些服务器端的功能嵌入到模板中,例如流程控制等
-
标签语法:
-
{%标签%} ....... {%结束标签%}
if标签
语法:
{%if 条件表达式1 %}
......
{%elif 条件表达式2 %}
......
{%elif 条件表达式3 %}
......
{% else %}
......
{% endif %}
for标签
{% for 变量 in 可迭代对象 %}
....循环语句
{% empty %}
....可迭代对象无数据填充的语句
{% endfor %}
内置变量-forloop
变量 | 描述 |
---|---|
forloop.counter | 循环的当前迭代(从1开始索引) |
forloop.counter0 | 循环的当前迭代(从0开始索引) |
forloop.revcounter | counter值倒序 |
forloop.revcounter0 | revcounter值倒序 |
forloop.first | 如果这是第一次通过循环,则为真 |
forloop.last | 如果这是最后一次循环,则为假 |
forloop.parentloop | 当嵌套循环,parentloop表示外层循环 |
九、模板层-过滤器和继承
9.1 模板过滤器
**定义:**在变量输出时对变量的值进行处理
**作用:**可以通过使用过滤器来改变变量的输出显示
语法:{{变量|过滤器1:‘参数值1’|过滤器2:‘参数值2’…}}
常用过滤器:
过滤器 | 说明 |
---|---|
lower | 将字符串转换为全部小写 |
upper | 将字符串转换为全部大写 |
safe | 默认不对变量内的字符串进行html转义 |
add:“n” | 将value的值增加n |
truncatechars:“n” | 如果字符串字符多于指定的字符数量,那么会截断。截断的字符将以可翻译的省略号序列结尾 |
9.2 继承
模板继承可以使父模板的内容重用,子模板直接继承父模板的全部内容并可以覆盖父模板中相应的块
语法﹣父模板中:
- 定义父模板中的块 block 标签
- 标识出哪些在子模块中是允许被修改的
- block 标签:在父模板中定义,可以在子模板中覆盖
语法﹣子模板中:
-
继承模板 extends 标签(写在模板文件的第一行)
例如{% extends 'base . html‘ %}
-
子模板重写父模板中的内容块
{% block b1ock_ name %}
子模板块用来覆盖父模板中 block _ name 块的内容
{% endb1ock b1ock_name %}
重写的覆盖规则
- 不重写,将按照父模板的效果显示
- 重写,则按照重写效果显示
注意
- 模板继承时,服务器端的动态内容无法继承
十、url反向解析
10.1 介绍
url 反向解析是指在视图或模板中,用 path 定义的名称来动态查找或计算出相应的路由
path 函数的语法
- path ( route , views , name ="别名)
- path (’ page ', views . page _ view , name =" page _ url ")
根据 path 中的 name =关键字传参给 url 确定了个唯一确定的名字,在模板或视图中,可以通过这个名字
反向推断出此 url 信息
10.2 模板中
通过 url 标签实现地址的反向解析
{% ur1 ‘别名’%}
{% url '别名' '参数值1' '参数值2'%}
10.3 在视图函数中
可调用 django 中的 reverse 方法进行反向解析
from django . urls import reverse
reverse ('别名', args =[], kwargs ={})
十一、 静态文件
11.1 静态文件配置
静态文件配置﹣ settings . py 中
-
配置静态文件的访问路径【该配置默认存在】
通过哪个 url 地址找静态文件
STATIC _ URL =’/ static /’
说明:
指定访问静态文件时是需要通过/static/xxx 或http://127.0.0.1:8000/static/xxx
[ xxx 表示具体的静态资源位置]
-
配置静态文件的存储路径 STATICELLES DIRS
STATICFILES _ DIRS 保存的是静态文件在服务器端的存储位置
#file:setting.py
STATICFILES_DIRS =(
os.path .join(BASE_DIR ,"static"),
)
11.2 模板中访问静态文件- img 标签为例
通过 {% static %}标签访问静态文件
- 加载 static -{% load static %}
- 使用静态资源-{% static '静态资源路径'%}
- 样例
<img src="{% static 'images/lena.jpg'%}">
十二、Django应用及分布式路由
12.1 应用
介绍:
应用在 Django 项目中是一个独立的业务模块,可以包含自己的路
由,视图,模板,模型
创建应用
-
用 manage . py 中的子命令 startapp 创建应用文件夹
python3 manage . py startapp 【自定义文件名】
-
在 settings . py 的 INSTALLED _ APPS 列表中配置安装此应用
12.2 分布式路由
配置分布式路由
步骤一、主路由中调用 include 函数
语法: include (’ app 名字. url 模块名)
作用:用于将当前路由转到各个应用的路由配置文件的 urlpatterns 进行分布式处理
from django.contrib import admin
from django.urls import path,include
from hsx_Django2 import views
urlpatterns = [
path('admin/', admin.site.urls),
path("test_static",views.test_static),
path('music/',include('music.urls')),
path('sport/',include('sport.urls')),
path('news/',include('news.urls'))
]
步骤2、应用下配置 urls . py
应用下手动创建 urls . py 文件
内容结构同主路由完全一样
from django.urls import path
from .import views
urlpatterns = [
path('index',views.index_view)
]
12.3、应用下的模板
应用内部可以配置模板目录
-
应用下手动创建 templates 文件夹
-
settings . py 中开启应用模板功能
TEMPLATE 配置项中的' APP _ DIRS '值为 True 即可
应用下 templates 和外层 templates 都存在时, django 得查找模板规则
- 优先查找外层 templates 目录下的模板
- 按 INSTALLED _ APPS 配置下的应用顺序逐层查找
十三、模型层及ORM
13.1 模型层
介绍
定义:负责跟数据库之间进行通信
Django 配置 mysql (linux ubuntu)
- 安装 mysqlclient [版本 mysqlclient 1.3.13以上,官网目前为14.x]
- 安装前确认 ubuntu 是否已安装python3-dev和 default-libmysqlclient - dev
sudo apt list --instaledlgrep -E 'libmysqlclient-dev|python3-dev ‘
- 若命令无输出则需要安装-
sudo apt - get instal python3-dev default-libmysqlclient-dev
-
sudo pip3 install mysqlclient
更改setting.py数据库配置项
#setting.py mysql数据库配置项
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME':'hsx_db',
'USER':"root",
'PASSWORD':'123456',
'HOST':"127.0.0.1",
"PORT":"3306"
}
}
-
ENGINE -指定数据库存储引擎
'django.db.backends.mysq1' 'django.db.backends.sq1ite39' 'django.db.backends. oracle' 'django.db.backends.postgresq1'
-
NAME ﹣指定要连接的数据库的名称
-
USER ﹣指定登录到数据库的用户名
-
PASSWORD ﹣数据库的密码
-
HOST / PORT ﹣连接具体数据库的 IP 和端口
模型
- 模型是一个 Python 类,它是由 django.db.models.Model 派生出的子类。
- 一个模型类代表数据库中的一张数据表
- 模型类中每一个类属性都代表数据库中的一个字段。
- 模型是数据交互的接口,是表示和操作数据库的方法和方式
13.2 ORM框架
介绍
定义
- ORM ( Object Relational Mapping )即对象关系映射,它是一种程序技术,它允许你使用类和对象对数据库进行操作,从而避免通过 SQL 语句操作数据库
作用
- 建立模型类和表之间的对应关系,允许我们通过面向对象的方式来操作数据库。
- 根据设计的模型类生成数据库中的表格。
- 通过简单的配置就可以进行数据库的切换。
优点
只需要面向对象编程,不需要面向数据库编写代码.
- 对数据库的操作都转化成对类属性和方法的操作.
- 不用编写各种数据库的 sqI 语句.
实现了数据模型与数据库的解耦,屏蔽了不同数据库操作上的差异.
- 不在关注用的是 mysqI 、oracle .….等数据库的内部细节.
- 通过简单的配置就可以轻松更换数据库,而不需要修改代码
模型类-创建
from django.db import models
class 模型类名(models.Model):
字段名=models.字段类型(字段选项)
示例:
from django.db import models
#Book
class Book(models.Model):
#title和price是类属性,也等于数据库字段,CharField和DecimalField是字段类型
title=models.CharField('书名',max_length=50,default='')
price=models.DecimalField('定价',max_digits=7,decimal_places=2,default=0.0)
数据库迁移
迁移是 Django 同步您对模型所做更改(添加字段,删除模型等)到您的数据库模式的方式
-
生成迁移文件-执行 <python3 manage . py makemigrations>
将应用下的 models . py 文件生成一个中间文件,并保存在 migrations 文件夹中
-
执行迁移脚本程序﹣执行 <python3 manage . py migrate>
执行迁移程序实现迁移。将每个应用下的 migrations 目录中的中间文件同步回数据库
ORM-基础字段及选项1
字段类型
-
BooleanField()
-
数据库类型: tinyint (1)
-
编程语言中:使用 True 或 False 来表示值
-
在数据库中:使用1或0来表示具体的值·
-
-
CharField
-
数据库类型: varchar
-
注意:必须要指定 max _ length 参数值
-
-
DateField ()
-
数据库类型: date
-
作用:表示日期
-
参数:
-
auto _ now :每次保存对象时,自动设置该字段为当前时间(取值: True / False )
-
auto _ now _ add :当对象第一次被创建时自动设置当前时间(取值: True / False )。
-
default :设置当前时间(取值:字符串格式时间如:'2019-6-1)。
以上三个参数只能多选一
-
-
-
DateTimeField()
-
数据库类型: datetime (6)
-
作用:表示日期和时间
-
参数同 DateField
-
-
FloatField()
-
数据库类型: double
-
编程语言中和数据库中都使用小数表示值
-
-
DecimalField()
-
数据库类型: decimal (×, y )
-
编程语言中:使用小数表示该列的值
-
在数据库中:使用小数
-
参数:
-
max _ digits :位数总数,包括小数点后的位数。该值必须大于等于 decimal _ places
-
decimal _ places :小数点后的数字数量
-
-
-
ImageField ()
-
数据库类型: varchar (100)
-
作用:在数据库中为了保存图片的路径
-
编程语言和数据库中使用字符串
-
-
TextField()
-
数据库类型: longtext
-
作用:表示不定长的字符数据
-
-
EmailField()
-
数据库类型 varchar
-
编程语言和数据库中使用字符串
-
-
IntegerField()
-
数据库类型: int
-
编程语言和数据库中使用整数
-
字段选项
-
**字段选项:**指定创建的列的额外的信息
-
允许出现多个字段选项,多个选项之间使用,隔开
-
primary _ key
- 如果设置为 True ,表示该列为主键,如果指定一个字段为主键,则此数库表不会创建 id 字段
-
blank
- 设置为 True 时,字段可以为空。设置为 False 时,字段是必须填写的
-
null
-
如果设置为 True ,表示该列值允许为空。
-
默认为 False ,如果此选项为 False 建议加入 default 选项来设置默认值
-
-
default
- 设置所在列的默认值,如果字段选项 null = False 建议添加此项
-
db _ index
- 如果设置为 True ,表示为该列增加索引
-
unique
- 如果设置为 True ,表示该字段在数据库中的值必须是唯一(不能重复出现的)
-
db _ column
- 指定列的名称,如果不指定的话则采用属性名作为列名
-
verbose _ name
- 设置此字段在 admin 界面上的显示名称
-
字段选项样例
#创建一个属性,表示用户名称,长度30个字符,必须是唯一的,不能为空,添加索引 name=models.CharField (max_length =30,unique=True,nu11= False,db_index=Tru)
Meta类
使用内部 Meta 类来给模型赋予属性, Meta 类下有很多内建的类属性,可对模型类做一些控制
示例:
#file : bookstore/models.py
from django.db import models
class Book (models.Model):
title=models.charField ("书名",max_length =50, default ='')
price=models.DecimalField ("定价",max_digits =7,decima1_p1aces=2,default=0.0)
clasS Meta :
db_table='book' #可改变当前模型类对应的表名
ORM操作
管理器对象
每个继承自 models . Model 的模型类,都会有一个 objects 对象被同样继承下来。这个对象叫管理器对象
数据库的增删改查可以通过模型的管理器实现
class MyMode1( models .Mode1):
.....
MyMode1.objects. create (...)# objects 是管理器对象
创建数据
Django ORM 使用一种直观的方式把数据库表中的数据表示成
Python 对象
- 创建数据中每一条记录就是创建一个数据对象
方案1
MyModel . objects . create (属性1=值1,属性2=值1…)
- 成功:返回创建好的实体对象
- 失败:拋出异常
方案2
创建 MyModel 实例对象,并调用 save()进行保存
obj =MyMode1(属性=值,属性=值)
obj.属性=值
obj.save()
查询操作
查询简介
- 数据库的查询需要使用管理器对象进行
- 通过 MyModel . objects 管理器方法调用查询方法
方法 | 说明 |
---|---|
all() | 查询全部记录,返回 QuerySet 查询对象 |
get() | 查询符合条件的单一记录 |
filter() | 查询符合条件的多条记录 |
exclude() | 查询符合条件之外的全部记录 |
查询方法
-
all()方法
用法:MyModel . objects . all()
**作用:**查询 MyModel 实体中所有的数据
等同于 select * from tabel
返回值:QuerySet 容器对象,内部存放 MyModel 实例
from bookstore . models import Book books = Book . objects .a11O for book in books : print(book.title,book.pub)
-
values (`列1’,列2’.)
用法: MyModel . objects . values (…)
**作用:**查询部分列的数据并返回
等同于 select 列1,列2 from XXX
返回值: QuerySet
- 返回查询结果容器,容器内存字典,每个字典代表一条数据,
- 格式为:{’列1’:值1,'列2’:值2}
-
values _ list (列1,‘列2’)
用法: MyModel . objects . values _ list (…)
**作用:**返回元组形式的查询结果
等同于 select 列1,列2 from XXX
返回值: QuerySet 容器对象,内部存放元组
- 会将查询出来的数据封装到元组中,再封装到查询集合 QuerySet 中
-
order _ by
用法: MyModel . objects . order _ by (`﹣列,列)
**作用:**与all()方法不同,它会用 SQL 语句的 ORDER BY 子句对查询结果进行根据某个字段选择性的进行 排序
说明:
默认是按照升序排序,降序排序则需要在列前增加’-'表示
条件方法
-
filter (条件)
语法: MyModel . objects . filter (属性1=值1,属性2=值2)
**作用:**返回包含此条件的全部的数据集
返回值:
QuerySet 容器对象,内部存放 MyModel 实例说明:
当多个属性在一起时为"与"关系,即当
-
get (条件)
语法: MyModel . objects . get (条件)
**作用:**返回满足条件的唯一一条数据
**说明:**该方法只能返回一条数据,查询结果多余一条数据则抛出出, Model . MultipleObjectsReturned 异常,查询结果如果没有数据则拋出 Model . DoesNotExist 异常
查询谓词
**定义:**做更灵活的条件查询时需要使用查询谓词
**说明:**每一个查询谓词是一个独立的查询功能
**_ exact :**等值匹配
示例:
Author.objects.filter(id_exact=1)
#等同于 select * from author where id =1
- **__gt :**大于指定值
样例:Author.objects.filer(age_gt =50)
#等同于 select * from author where age >50
- **__gte :**大于等于
- **__It :**小于
- **__Ite :**小于等于
更新数据
-
更新单个数据
修改单个实体的某些字段值的步骤:
- 查
- ﹣通过 get()得到要修改的实体对象
- 改
- -通过对象.属性的方式修改数据
- 保存
- -通过对象.save() 保存数据
- 查
-
批量更新数据
直接调用 QuerySet 的 update (属性=值)实现批量修改
示例:
#将 id 大于3的所有图书价格定为0元
books = Book.objects.filter (id__gt=3)
books.update(price=0)
#将所有书的零售价定为100元 books = Book . objects .all()
books.update(market_price=100)
删除数据
单条数据删除
-
查找查询结果对应的一个数据对象
-
调用这个数据对象的delete()方法实现删除
try:
auth = Author.objects.get(id=1)
auth.delete()
except:
print(删除失败)
批量删除
-
查找查询结果集中满足条件的全部QuerySet查询集合对象
-
调用查询集合对象的delete()方法实现删除
#删除全部作者中,年龄大于65的全部信息
auths = Author.objects.filter(age_gt=65)
auths.delete()
伪删除
- 通常不会轻易在业务里把数据真正删掉,取而代之的是做伪删除,即在表中添加一个布尔型字段(is_active),默认是True;执行删除时,将欲删除数据的is_active字段置为False
- 注意:用伪删除时,确保显示数据的地方,均加了is_active=True的过滤查询
F对象和Q对象
F 对象
-
一个 F 对象代表数据库中某条记录的字段的信息
-
作用:
-
通常是对数据库中的字段值在不获取的情况下进行操作
-
用于类属性(字段)之间的比较。
-
-
语法
from django . db . models import F
F ('列名')
示例1:更新 Book 实例中所有的零售价涨10元
Book.objects.a11().update(market_price=F('market _ price')+10)
'UPDATE `bookstore_book` SET market_price=(`bookstore_book`,` market_price+10)
#以上做法好于如下代码
books=Book.objects.all()
for book in books:
book.market_price=book.marget_price +10
book.save()
示例2:对数据库中两个字段的值进行比较,列出哪儿些书的零售价高于定价?
from django.db.models import F
from bookstore.models import Book
books=Book.objects.filter(market_price__gt=F('price'))
SELECТ * FROМ `bookstore_book` WHERE `bookstore_book`,`marke_price`>(`bookstore_book `,`price`)
for book in books:
print (book.title ,‘定价:',book.price,‘现价:',book.market_price)
Q 对象
当在获取查询结果集使用复杂的逻辑或小逻辑非~等操作时可以借助于 Q 对象进行操作
**如:**想找出定价低于20元或清华大学出版社的全部书,可以写成
Book.objects.filter(Q(price_lt=20)|Q(pub ="清华大学出版社"))
Q 对象在数据包 django . db . models 中。需要先导入再使用
**作用:**在条件中用来实现除 and (&)以外的 or ( l )或 not (~)操作
运算符:
- &与操作
- |或操作
- ~非操作
语法:
from django.db.models import Q
Q (条件1)|Q(条件2)#条件1成立或条件2成立
Q (条件1)&Q(条件2)#条件1和条件2同时成立
Q (条件1)&~Q(条件2)#条件1成立且条件2不成立
示例:
from django.db.models import Q
#查找清华大学出版社的书或价格低于50的书
Book.objects.filter(Q(market_price__lt =50)|Q(pub_house='清华大学出版社'))
#查找不是机械工业出版社的书且价格低于50的书
Book.objects.filter(Q(market_price_lt=50)&~Q(pub_house='机械工业出版社'))
聚合查询
聚合查询是指对一个数据表中的一个字段的数据进行部分或全部进行统计查询,查 bookstore _ book 数据表中的全部书的平均价格,查询所有书的总个数等,都要使用聚合查询
聚合查询分为:
-
整表聚合
-
分组聚合
聚合查询﹣整表聚合
不带分组的聚合查询是指导将全部数据进行集中统计查询
- 导入方法:
from django . db . models import *
- 聚合函数:
Sum , Avg , Count , Max , Min
- 语法:
MyModel . objects . aggregate (结果变量名=聚合函数(列'))
- **返回结果:**结果变量名和值组成的字典
- 格式为:{“结果变量名”:值}
聚合查询﹣分组聚合
分组聚合是指通过计算查询结果中每一个对象所关联的对象集合,从而得出总计值(也可以是平均值或总和),即为查询集的每一项生成聚合。**
-
语法:
QuerySet . annotate (结果变量名=聚合函数('列'))
-
返回值;
QuerySet
原生数据库操作
Django 也可以支持直接用 sqI 语句的方式通信数据库
- **查询:**使用 MyModel . objects , raw ()进行数据库查询操作
- 查询语法: MyModel . objects . raw ( sql 语句,拼接参数)
- 返回值: RawQuerySet 集合对象【只支持基础操作,比如循环】
books=models.Book.objects.raw('select * from bookstore_book')
for book in books :
print ( book )
SQL 注入
使用原生语句时小心 SQL 注入
- **定义:**用户通过数据上传,将恶意的 sqI 语句提交给服务器,从而达到攻击效果
- **案例:**用户在搜索好友的表单框里输入’1 or 1=1'
s1=Book.objects.raw(
select from bookstore _ book where id =% s '%(‘1 or 1=1’))
攻击结果:可查询出所有用户数据
cursor
完全跨过模型类操作数据库﹣查询/更新/删除
- 导入 cursor 所在的包
from django.db import connection
- 用创建 cursor 类的构造函数创建 cursor 对象,再使用 cursor 对象,为保证在出现异常时能释放 cursor 资源,通常使用 with 语句进行创建操作
from django.db import connection
with connection.cursor() as cur :
cur.execute ('执行SQL 语句','拼接参数')
十四、admin后台管理
- **创建后台管理账号——该账号为管理后台最高权限账号 **
python manage.py createsuperuser
注册自定义模型类
- 为后台管理界面添加便于操作的新功能
- 后台管理类器必须继承django.contrib.admin里面的ModelAdmin类
from .models import *
class BookManager(admin.ModelAdmin):
#列表页显示哪些字段的列
list_display = ['id','title','pub','price','market_price']
#控制List_display中的字段,哪有可以连接到修改页
list_display_links = ['title']
#添加过滤器
list_filter = ["pub"]
#添加搜索框[模糊查询]
search_fields = ['title']
#添加可更改的字段
list_editable = ['price']
admin.site.register(Book,BookManager)
Meta类定义admin显示名字
在model.py文件
class Meta:
db_table='book'
#给模型对象的一个易于理解的名称(单数),用于显示在admin管理界面
verbose_name='图书'
#复数名称,用于显示在admin管理界面
verbose_name_plural=verbose_name
十五、关系映射
在关系型数据库中,通常不会把所有数据都放在同一张表中,不易于扩展
常见关系映射有:
-
一对一映射 如:一个身份证对应一个人
-
一对多映射 如:一个班级可以有多个学生
-
多对多映射 如:一个学生可以报多个课程,一个课程可以有多个学生学习
一对一映射
【创建】
- 一对一是表示现实事物间存在的一对一的对应关系。
- 如:一个家庭只有一个户主,一个男人有一个妻子,一个人有一个唯一的指纹信息等
- 语法:
OneToOneField (类名,on_delete=xxx )
class Author(models.Model):
name=models.CharField('姓名',max_length=11)
class Wife(models.Model):
name=models.CharField('姓名',max_length=11)
author=models.OneToOneField(Author,on_delete=models.CASCADE)
- 特殊字段选项【必须】
- on _ delete -级联删除
-
models.CASCADE 级联删除。 Django 模拟 SQL 约束 ON DELETE CASCADE 的行为,并删除包含
ForeignKey 的对象。
-
models.PROTECТ抛出 ProtectedError 以阻止被引用对象的删除;[等同于 mysql默认的 RESTRICТ]
-
SET_NULL 设置 ForeignKey nul ;需要指定 nul=True
-
SET_DEFAULT 将 ForeignKey 设置为其默认值;必须设置 ForeignKey 的默认值
【创建数据】
-
无外键的模型类[ Author ]:
author1= Author .objects.create ( name ='王老师')
-
有外键的模型类[ Wife ]
wife1= Wife.objects.create(name ='王夫人',author=author1)#关联王老师 obj
wife1= Wife.objects.create(name ='王夫人'author_id =1)#关联王老师对应主键值
【查询数据】
1、正向查询:直接通过外键属性查询,则称为正向查询
#通过 wife 找 author
from.models import Wife
wife = Wife.objects.get(name='王夫人‘)
print ( wife.name ,‘的老公是’, wife.author.name )
2、反向查询﹣没有外键属性的一方,可以调用反向属性查询到关联的另一方
反向关联属性为实例对象.引用类名(小写),如作家的反向引用为作家对象.wife
----当反向引用不存在时,则会触发异常
author1= Author.objects.get (name ='王老师')
author1.wife.name
一对多映射
一对多是表示现实事物间存在的一对多的对应关系。
**如:**一个学校有多个班级,一个班级有多个学生,一本图书只能属于一个出版社,一个出版社允许出版多本图书
一对多需要明确出具体角色,在多表上设置外键
【创建】
语法:当一个A类对象可以关联多个B类对象时
class A(models.Model):
.....
class Wife(models.Model):
属性=models.ForeignKey("一"的模型类,on_delete=xx)
ForeignKey必须指定on_delete模式
【创建数据】
先创建’一’,在创建’多‘
from .models import *
pub1=Publisher.objects.create(name='清华大学出版社')
Book.objects.create(title='C++',publisher=author1)
Book.objects.create(title='Java',publisher_id=1)
【查询数据】
1,正向查询[通过 Book 查询 Publisher ]
#通过pub1isher属性查询即可 book.publisher
abook = Book.objects.get(id =1)
print( abook.title ,'的出版社是:', abook.publisher.name )
2,反向查询[通过 Publisher 查询对应的所有的 Book ]
需要用到反向属性xxx_set
#通过出版社查询对应的书
pub1= Publisher.objects.get( name =‘清华大学出版社’)
books =pub1.book_set.a11()#通过book_set 获取pub1对应的多个 Book 数据对象
#books = Book.objects.filter(publisher =pub1)
#也可以采用此方式获取
print ('清华大学出版社的书有')
for book in books :
print ( book.title )
多对多映射
定义
**多对多表达对象之间多对多复杂关系,**如:每个人都有不同的学校(小学,初中,高中,.…),每个学校都有
不同的学生…
- mysql 中创建多对多需要依赖第三张表来实现
- Django 中无需手动创建第三张表, Django 自动完成
- 语法:在关联的两个类中的任意一个类中,増加:
属性=models.ManyToManyField ( MyModel )
【创建】
用法示例:
- 一个作者可以出版多本图书
- 一本图书可以被多名作者同时编写
class Author(models.Mode1):
....
class Book(models.Mode1):
....
authors=models.ManyToManyField ( Author )
【创建数据】
#方案1先创建 author 再关联 book
author1= Author.objects.create(name ='吕老师')
author2= Author.objects.create(name ='王老师')
#吕老师和王老师同时写了一本 Python
book11=author1.book_set.create(titl ="Python")
author2book_set.add(book11)
#方案2先创建 book 再关联 author
book = Book.objects.create(title ='python1')
#郭小闹和吕老师都参与了python1的创作
author3= book.authors.create(name='guoxiaonao')
book.authors.add(author1)
【查询数据】
1,正向查询有多对多属性的对象查另一方
- 通过 Book 查询对应的所有的 Author
- 此时多对多属性等价于 objects
book.authors.a11() ->获取 book 对应的所有的 author 的信息
book.authors.filter(age__gt=80) ->获取 book 对应的作者中年龄大于80岁的作者的信息
2,反向查询
通过 Author 查询对应的所有的 Book 利用反向属性 book _ set
author.book_set.a11()
author.book_set.filter()
十六、Cookies和session
会话
Cookies和Session就是为了保持会话状态而诞生的两种存储技术**
Cookies
定义
- cookies 是保存在客户端浏览器上的存储空间
Cookies 特点
- cookies 在浏览器上是以键-值对的形式进行存储的,键和值都是以 ASCII 字符串的形存储(不能是中文字符串)
- 存储的数据带有生命周期
- cookies 中的数据是按域存储隔离的,不同的域之间无法访问
- cookies 的内部的数据会在每次访问此网址时都会携带到服务器端,如果 cookies 过大会降低响应速度
Cookies 的使用﹣存储
HttpResponse.set_cookie( key,value =",max_age=None,expires=None)
- key : cookie 的名字
- value : cookie 的值
- max _ age : cookie 存活时间,秒为单位
- **expires :**具体过期时间
- 当不指定 max _ age 和 expires 时,关闭浏览器时此数据失效
存储示例:
-
添加 cookie
#为浏览器添加键为 my_var1,值为123,过期时间为1个小时的cookie responds=HttpResponse("己添加 my _var1,值为123") responds.set_cookie('my _var1',123,3600) return responds
-
修改 cookie
#为浏觉器添加键为 my_var1,修改值为456,过期时间为2个小时的 cookie responds=HttpResponse("已修改 my _var1,值为456") responds.set_cookie ('my _var1',456,3600*2) return responds
Cookies 的删除&获取
-
删除 Cookies
-
HttpResponse.delete_cookie(key)
- 删除指定的 key 的 Cookie 。如果 key 不存在则什么也不发生
-
获取 Cookies
-
- 通过 request . CQOKIES 绑定的字典( dict )获取客户端的 COOKIES 数据
value = request.COOKIES.get ('cookies名',‘默认值)
- 通过 request . CQOKIES 绑定的字典( dict )获取客户端的 COOKIES 数据
Session
定义
session 是在服务器上开辟一段空间用于保留浏览器和服务器交互时的重要数据
实现方式:
-
使用 session 需要在浏览器客户端启动 cookie ,且在 cookie 中存储 sessionid
-
每个客户端都可以在服务器端有一个独立的 Session ﹣注意:不同的请求者之间不会共享这个数据,与
请求者一一对应
session 初始配置
settings . py 中配置 session
- 向 INSTALLED_APPS 列表中添加:
INSTALLED _ APPS =[
#启用 sessions 应用
'django.contrib.sessions',
]
- 向 MIDDLEWARE 列表中添加:
MIDDLEWARE =[
#启用 session 中间件
'django.contrib.sessions.midd1eware.SessionMidd1eware'
]
session 的使用
session 对于象是一个类似于字典的 SessionStore 类型的对象,可以用类拟于字典的方式进行操作
session 能够存储如字符串,整型,字典,列表等。
- 保存 session 的值到服务器
request.session ['KEY']= VALUE
- 获取 session 的值
value = request.session['KEY']
value=request.session.get('KEY',默认值)
- 删除 session
del request.session [' KEY ']
settings.py 中相关配置项
- SESSION _ COOKIE _ AGE
- 作用:指定 sessionid 在 cookies 中的保存时长(默认是2周),如下:
- 例如: SESSION_COOKIE_AGE =60 * 60 * 24 * 7 * 2
- SESSION_EXPIRE_ AT_BROWSER_CLOSE=True
- 设置只要浏览器关闭时,session就失效(默认为False)
注意: Django 中的 session 数据存储在数据库中,所以使用 session 前需要确保已经执行过 migrate
Django session 的问题
-
django_session 表是单表设计;
且该表数据量持续增持【浏览器故意删掉 sessionid &过期数据未删除】
-
可以每晚执行python3 manage . py clearsessions
【该命令可删除已过期的 session 数据】
sponds.set_cookie (‘my _var1’,456,3600*2)
return responds
```
Cookies 的删除&获取
-
删除 Cookies
-
HttpResponse.delete_cookie(key)
- 删除指定的 key 的 Cookie 。如果 key 不存在则什么也不发生
-
获取 Cookies
-
- 通过 request . CQOKIES 绑定的字典( dict )获取客户端的 COOKIES 数据
value = request.COOKIES.get ('cookies名',‘默认值)
- 通过 request . CQOKIES 绑定的字典( dict )获取客户端的 COOKIES 数据
Session
定义
session 是在服务器上开辟一段空间用于保留浏览器和服务器交互时的重要数据
实现方式:
-
使用 session 需要在浏览器客户端启动 cookie ,且在 cookie 中存储 sessionid
-
每个客户端都可以在服务器端有一个独立的 Session ﹣注意:不同的请求者之间不会共享这个数据,与
请求者一一对应
session 初始配置
settings . py 中配置 session
- 向 INSTALLED_APPS 列表中添加:
INSTALLED _ APPS =[
#启用 sessions 应用
'django.contrib.sessions',
]
- 向 MIDDLEWARE 列表中添加:
MIDDLEWARE =[
#启用 session 中间件
'django.contrib.sessions.midd1eware.SessionMidd1eware'
]
session 的使用
session 对于象是一个类似于字典的 SessionStore 类型的对象,可以用类拟于字典的方式进行操作
session 能够存储如字符串,整型,字典,列表等。
- 保存 session 的值到服务器
request.session ['KEY']= VALUE
- 获取 session 的值
value = request.session['KEY']
value=request.session.get('KEY',默认值)
- 删除 session
del request.session [' KEY ']
settings.py 中相关配置项
- SESSION _ COOKIE _ AGE
- 作用:指定 sessionid 在 cookies 中的保存时长(默认是2周),如下:
- 例如: SESSION_COOKIE_AGE =60 * 60 * 24 * 7 * 2
- SESSION_EXPIRE_ AT_BROWSER_CLOSE=True
- 设置只要浏览器关闭时,session就失效(默认为False)
注意: Django 中的 session 数据存储在数据库中,所以使用 session 前需要确保已经执行过 migrate
Django session 的问题
-
django_session 表是单表设计;
且该表数据量持续增持【浏览器故意删掉 sessionid &过期数据未删除】
-
可以每晚执行python3 manage . py clearsessions
【该命令可删除已过期的 session 数据】