目录
参考源码:https://github.com/hilqiqi0/AI/tree/master/3.Web/django
一、WEB、服务器和框架
1、WEB 与 服务器
2、框架
二、Django框架
1、什么是Django
2、Django的框架模式 - MTV
3、Django的使用
4、Django项目结构介绍
三、URL的使用
1、urls.py
2、url函数
3、通过 url 向 views 传参
四、Django中的应用
1、什么是应用
2、创建应用
五、Django 的模板(Templates)
1、什么是模板
2、模板的设置
3、模板的加载方式
4、模板的语法
5、静态文件
6、模板的继承
7、url() 的 name 参数
六、模型 - Model
1、什么是模型
2、创建和使用模型 - ORM
3、创建 和 配置数据库
4、数据库的同步操作
5、编写Models
6、字段类型和字段选项
7、数据的版本切换
8、通过数据库自动导出Models
七、模型中的 CRUD
1、通过 ORM 向 DB 中增加数据
2、查询操作(重难点)
3、修改数据
4、删除数据
八、转发 与 重定向
九、ORM 操作补充
1、F()操作
2、Q()操作
3、原生的数据库操作方法
十一、使用后台管理 Models
1、后台的配置
2、基本管理
3、高级管理
十二、关系映射
1、一对一映射
2、一对多(1:M)
3、多对多(M:N)
十三、自定义查询对象 - objects
十四、HttpRequest
1、HTTP 协议
2、HttpRequest介绍
3、CSRF 跨站点攻击
4、地址栏拼参数
十五、使用 forms 模块处理表单
1、forms 模块的作用
2、使用 forms 模块
3、在模板中解析 form 对象
4、使用 forms.Form 获取表单数据
5、forms 的高级处理
6、内置小部件
十七、session - 会话
1、什么是session
2、在 Django 中使用session
3、在 settings.py中,有关session的设置
十八、附录:目录
1、WEB :表示用户可以浏览的网页内容(HTML,CSS,JS)
2、服务器
能够给用户提供服务的机器
1、硬件 与 软件
硬件范畴:一台机器
软件范畴:一个能够接收用户请求并给出响应的程序
1、APACHE
2、TOMCAT
3、IIS
4、Nginx
... ...
2、作用
1、存储WEB所需要的信息(HTML,图片,文件,..)
2、能够处理用户的请求(request),并给出响应(response)
3、执行服务器端程序:数据库操作
3、WEB 与 服务器之间的关系
4、Django框架
使用python语言来开发服务器端处理程序
1、什么是框架
框架是一个为了解决开放性问题而存在的一种结构。框架本身提供了一些最基本的功能。我们只需要在框架的基础功能之上搭建属于自己的操作即可。
2、Python中的框架
1、Django :重量级的WEB框架
2、Tornado :异步框架
3、Flask :轻量级的WEB框架
... ...
是一个开源框架,2005年发布,采用Python语言开发。早期是做新闻以及内容管理的网站的。提供了非常强大的后台管理系统。
M :Models 层
模型层,负责数据库的建模以及CRUD的操作
T :Templates 层
模板层,用于处理用户显示的内容,如HTML
V :Views 层
视图层,处理与用户交互的部分操作,从模型中获取数据,再将数据发送给模板,并显示给用户
自己了解:MVC
M :Models 模型层
模型层,负责数据库的建模以及CRUD的操作
V :Views 视图层
用于处理用户显示的内容
C :Controllers 控制层
处理与用户交互的部分内容,从模型中获取数据,再交给视图层,再显示给用户
M ---- M
T ---- V
V ---- C
1、Django介绍
Django官网:https://www.djangoproject.com/
DjangoBook: http://djangobook.py3k.cn/2.0/
2、Django的安装
1、查看已安装的Django版本
1、进入到终端 以及 python 的交互模式
python3 / ipython3
2、在交互模式中 输入 import django
如果未报错:说明已经安装过django
如果报错:说明从未安装
3、查看已安装的版本
交互模式中:django.VERSION
2、安装
1、在线安装 - 使用 pip / pip3
sudo pip3 install django
(默认安装的Django最高版本)
sudo pip3 install django==1.11.8
(指定安装1.11.8版本)
2、离线安装
1、下载所需Django安装包
2、在环境中解压Django包
tar -xvf Django-1.11.8.tar.gz
3、进入到 Django-1.11.8 中
4、安装
sudo python3 setup.py install
3、使用Django
1、创建Django项目
使用 django-admin 指令,创建Django项目
django-admin startproject 项目名
练习:
1、创建一个目录,Django
2、在Django目录中,创建项目 first
3、查看first目录中的结构
2、启动服务,用于访问
使用 manage.py 文件 启动服务
python3 manage.py runserver
3、访问网站
启动服务成功后,在浏览器中,通过以下地址访问:
http://127.0.0.1:8000
http://localhost:8000
http://localhost:8000/admin
1、manage.py
负责执行django中的各项操作文件
如:
启动服务
创建管理员
创建应用
数据库的同步操作
调用方式:
1、python3 manage.py 子命令
2、./manage.py 子命令
注:
修改manage.py首行:
#!/usr/bin/env python ==> #!/usr/bin/env python3
2、主目录(名称与项目名称相同)
1、__init__.py
项目初始化文件,每当服务器启动的时候,都会自动执行
2、urls.py
项目的基础url(路由)配置文件
3、wsgi.py
应用服务器配置文件
4、settings.py
项目的主设置文件
1、BASE_DIR
获取当前项目的根目录路径
2、DEBUG :调试模式
开发过程:推荐使用True
上线运行:推荐改为False
3、ALLOWED_HOSTS
设置允许访问本项目的地址列表
如果不设置的话,只有本机能访问(localhost/127.0.0.1)能访问
推荐写'*',表示任何地址都允许访问该项目(局域网)
1、python3 manage.py runserver 0.0.0.0:8000
2、./manage.py runserver 0.0.0.0:8000
4、INSTALLED_APPS
指定已安装的应用,如果有自定义应用的话,需要在此位置进行注册
5、MIDDLEWARE
指定注册的中间件
6、ROOT_URLCONF
指定项目的基础路由配置文件
7、TEMPLATES:指定模板的信息
8、DATABASES:指定数据库的信息
9、LANGUAGE_CODE
指定网站的显示语言,如果要使用中文则可以修改为 zh-Hans
10、TIME_ZONE
指定时区,如果指定中国时区,则可以修改为 Asia/Shanghai
默认是在主目录中,主路由配置文件,会包含最基本的地址映射。
每个请求到达之后,都会由urls.py中的urlpatterns 列表中的url()进行匹配。
url()函数匹配上之后,可能将请求转交给其他的urls.py 或 视图(Views)去处理。
url函数的语法:
url(regex,views,kwargs=None,name=None)
1、regex
正则表达式,匹配请求的url
2、views
视图处理函数或其他的urls.py
3、kwargs
字典,用来向views传参,没有参数则可以省略
4、name
字符串,给url()起别名,主要在模板中使用
eg:
urlpatterns = [
url(r'^run/$',run_views),
]
1、使用正则表达式传参
使用子组传参,一个子组是一个参数,想要多个参数的话,可以使用多个子组
子组 - ()
urlpatterns = [
# 访问路径是run/的时候,交个run_views去处理
url(r'^run/$',run_views),
# 访问路径是run/任意两位数字,交给run_args_views去处理
url(r'^run/(\d{2})',run_args_views),
# 访问路径是run/四位数字/两位数字/,交给run1_views处理
url(r'^run/(\d{4})/(\d{2})/$',run1_views),
]
注意:
1、在url()中,一个子组()表示一个参数
2、在views.py中,对应的处理函数要根据url()中子组的个数,相应的定义参数,定义的参数要位于request之后
eg:
1、
url(r'^run/(\d{2})',run1_views),
def run1_views(request,num)
2、
url(r'^run/(\d{2})/(\d{4})',run2_views)
def run2_views(request,num1,num2)
2、使用url()第三个参数,字典传参
url(r'^show/$',show_views,{'name':'laoshe','age':'89'})
def show_views(request,name,age):
name:表示的就是字典name参数的值
age:表示的就是字典age参数的值
注意:
1、视图处理函数中,必须声明参数
2、参数的名称和位置,必须要与字典中的名称和位置保持一致
应用就是网站中的一个独立的程序模块
在Django中,主目录一般不处理用户的具体请求,主目录主要做的是项目的初始化和设置,以及请求的分发
1、命令
./manage.py startapp 应用名称
eg
./manage.py startapp news
2、在 settings.py 中进行注册
在 INSTALLED_APPS中进行注册
INSTALLED_APPS = [
'django.contrib.admin',
... ...,
'news',
]
3、应用的结构组成
1、migrations 目录
存放数据库中间文件(日志文件)
2、__init__.py
应用的初始化文件
3、admin.py
应用的后台管理配置文件
4、apps.py
应用的属性配置文件
5、models.py
模型文件,与数据库有关
6、tests.py
测试模块
7、views.py
定义视图的文件
练习:
1、创建 index 应用 ,并注册
2、创建 sport 应用 ,并注册
3、创建 music 应用 ,并注册
练习:
1、访问路径是
http://localhost:8000/sport/index
则交给 sport 应用中 index_views 视图处理
2、访问路径是
http://localhost:8000/music/index
则交个 music 应用中 index_views 视图处理
3、访问路径是
http://localhost:8000/index/index
则交给 index 应用中 index_views 视图处理
4、访问路径是
http://localhost:8000
则交给 index 应用中 index_views 视图处理
5、访问路径是
http://localhost:8000/login
则交给 index 应用中 login_views 视图处理
模板就是要动态的给用户呈现的网页内容
其实就是一个网页 - 前后端结合的一个网页
在 settings.py中 TEMPALTES 变量
TEMPLATES = [
{
'BACKEND':'... ...',
'DIRS':[... ...],
}
]
1、BACKEND:指定模板的搜索引擎,不用动
2、DIRS:指定模板所存放目录们
DIRS=['index.temp','music.temp']
但是,如果DIRS中为空的话,那么Django会自动到每个应用中去搜索一个叫 templates 的目录来作为模板的管理目录
推荐:
1、DIRS内容保持为空
2、在每个应用中,都创建一个 templates 目录
3、APP_DIRS
True:首先从DIRS中指定的目录中查找模板,如果没找到的话,再搜索templates目录
1、使用 loader 获取模板,并通过 HttpResponse进行响应
from django.template import loader
1、通过 loader 加载模板
t = loader.get_template('模板名称')
2、通过t对象,将模板渲染成字符串
html = t.render()
3、通过 HttpResponse 将 html 响应给 客户端
return HttpResponse(html)
2、使用 render 直接加载模板并返回
from django.shortcuts import render
return render(request,"模板名称")
1、变量
1、作用:允许将后端的数据传递给模板,在模板中,会根据变量的值进行显示
2、在Django中允许传递给模板做变量的数据类型
数字,字符串,列表,元组,字典,函数,对象
3、变量的语法
1、loader
dic = {
'变量名1':'值1',
'变量名2':'值2',
}
t = loader.get_template('xxx.html')
html = t.render(dic)
return HttpResponse(html)
在模板中显示变量:{{变量名}}
2、render
dic = {
'变量名1':'值1',
'变量名2':'值2',
}
return render(request,'xxx.html',dic)
练习:
访问 http://localhost:8000/news/05_exer
在模板中显示以下内容:
书名:《背影》
作者:朱自清
出版社:北京大学出版社
出版时间:1995-10-12
2、标签
1、什么是标签
允许将服务器端的一些功能嵌入到模板中
2、语法
{% 标签内容 %}
3、常用标签
1、for
{% for 变量 in 列表|元组|字典 %}
{% endfor %}
允许使用 for 提供的内置变量 - forloop
1、forloop.counter
记录当前循环的次数,从1开始
2、forloop.first
是否是第一次循环(第一项)
3、forloop.last
是否是最后一次循环(最后一项)
2、if
1、
{% if 条件 %}
满足条件运行的内容
{% endif %}
条件中允许使用 比较运算符(>,<,>=,<=,==,!=),逻辑运算符(not,and,or)
注意:and 和 or 不能同时出现
2、
{% if 条件 %}
满足条件运行的内容
{% else %}
不满足条件运行的内容
{% endif %}
3、
{% if 条件1 %}
满足条件1运行的内容
{% elif 条件2 %}
满足条件2运行的内容
{% elif 条件3 %}
满足条件3运行的内容
{% else %}
以上条件都不满足的时候运行的内容
{% endif %}
4、注意细节
不正确:{% if count==0 %}
正确:{% if count == 0 %}
说明:count==0会被当做一个字符串“count==0”,又因为找不到“count==0”而报错
3、过滤器
1、作用
过滤数据
在显示变量的数据之前,允许对数据进行筛选或改变
2、语法
{{变量|过滤器:参数}}
3、简单的过滤器
1、{{value|upper}}
将value变为大写字符
2、{{value|lower}}
将value编写小写字符
3、{{value|add:num}}
将num累加到value之后
4、{{value|floatformat:n}}
将value四舍五入到n位小数
5、{{value|truncatechars:n}}
将字符串截取到n位(包含...)
作业:
1、创建项目 - fruitday
2、创建应用 - index
3、配置 路由配置模块
4、将 login.html 移植到 fruitday 中,以模板的方式呈现给用户
1、什么是静态文件
不需要嵌入服务器端内容的文件,一律都是静态文件,如:图片,css,js,html 都是静态文件
2、Django中静态文件的处理
需要在settings.py 中设置静态文件的访问路径和存储路径
1、指定静态文件的访问路径
STATIC_URL=/static/
http://localhost:8000/static/***
作用:
当访问路径是 http://localhost:8000/static/*** 一律到静态文件存储路径中去搜索静态文件
2、定义静态文件的存储路径
STATICFILES_DIRS
STATICFILES_DIRS=(BASE_DIR,目录名)
允许在项目中以及所有的应用中都创建对应名称得到目录
STATICIFILES_DIRS=(BASE_DIR,static)
在项目的 static 目录中以及所有应用中的 static 目录中 存放的都是静态文件
3、访问静态文件
1、直接使用 localhost:8000/static/***/***
2、使用 {% static %} 访问静态资源
1、在模板的最顶层增加
{% load static %}
2、在使用静态文件时
{%static%}表示的就是静态文件的访问路径
1、什么是模板的继承
当多个模板(网页)具备大部分相同的内容时,就可以使用继承的方式,将相同的东西继承过来,再增加/修改属于自己的内容即可
2、模板继承的语法
1、在 父模板 中
必须要标识出来哪些内容是允许被修改的
标签:
{% block 名称 %}
父模板中正常显示的东西
{% endblock %}
block 的作用:
定义 在字模板中 允许被修改的地方
1、在父模板中,正常显示
2、在子模板中,如果不修改block内容的话则按照父模板中的内容正常显示
2、在子模板中
1、在最顶层增加一句话
{% extends '父模板的名称' %}
2、增加 block 标签,改写属于自己的内容
{% block 名称%}
子模板中的内容
{% endblock %}
子模板中的block会覆盖父模板中同名的block内容
url(regex,views,kwargs=None,name=None)
name:允许为当前的url设置别名,在Template中允许使用别名找到对应的 url
语法:
url(regex,views,name="别名")
在 模板中 使用 url 的别名
{% url '别名'%}
url(r'^admin_login/$',login_views,name="login")
模型,是根据数据库中数据表的结构来创建出来的class。每一张表到编程语言中就是一个class,表中的每一个列,到编程语言中就是class的一个属性。并且在模型中还可以完成对数据的CRUD操作
1、什么是ORM
ORM:Object Relational Mapping
中文:对象关系映射
简称:ORM,O/RM,O/R Mapping
三大特征:
1、数据表 到 类(class)的映射
将数据表 自动 生成一个 class 类
同时也允许将一个class类 自动生成数据库中的一张表
2、数据类型的映射
允许将表中的字段的数据类型 自动 映射成编程语言中对应的数据类型
也允许将编程语言的数据类型 自动 映射成 表中的字段的数据类型
3、关系映射
在编程语言中允许将表与表之间的关系映射出来
表与表之间的关系也可以自动映射到编程语言的class 中
数据库表中的关联关系:
一对一,一对多,多对多
2、ORM的优点
1、提高了开发的效率,能够自动完成表到对象的映射
2、不用SQL编码,也能够完成对数据的CRUD操作,可以省略庞大的数据访问层
1、创建数据库(支持中文)
create database 数据库名 default charset utf8 collate utf8_general_ci;
创建数据库:webdb
2、配置数据库(Django)
在 settings.py 中配置数据库的信息
DATABASES = {
'default':{
'ENGINE':'... ...',
'NAME':'...',
}
}
连接MySQL的配置如下:
1、ENGINE : 引擎
django.db.backends.mysql
2、NAME : 要连接到的数据库名
3、USER:登录到数据库的用户名,一般为root
4、PASSWORD:登录到数据库的密码
5、HOST:要连接的主机,本机的话 localhost 或 127.0.0.1
6、PORT:指定端口,MYSQL的是 3306
注意:
Django中连接mysql的话依赖 pymysql
安装:sudo pip3 install pymysql==0.7.11
在主目录中 __init__.py
import pymysql
pymysql.install_as_MySQLdb()
1、./manage.py makemigrations
作用:将每个应用下的 models.py 文件生成一个数据库的中间文件,并保存在migrations目录中
2、./manage.py migrate
作用:将每个应用下的 migrations 目录中的中间文件同步到数据库中
1、注意
1、Models中的每个class都称为 模型类(Model类),实体类(Entry/Entity)
2、Models中的每个模型类,必须继承自 models.Model
2、编写模型类
from django.db import models
class Entry(models.Model):
属性1 = models.字段类型(字段选项)
举个例子:
#创建一个 Publisher 模型类
#表示出版社信息,并包含以下属性
#1. name:表示出版社名称
#2.address:表示出版社地址
#3.city:表示出版社所在城市
#4.country:表示出版社所在国家
#5.website:表示出版社的网址
class Publisher(models.Model):
name = models.CharField(max_length=30)
address=models.CharField(max_length=50)
... ...
website=models.URLField()
1、字段类型(Field Type)
2、字段选项(Field Options)
练习:
在models.py 中追加2个class
1、Author - 作者
1、name - 姓名
2、age - 年龄
3、email - 邮箱(允许为空)
2、Book - 图书
1、title - 书名
2、publicate_date - 出版时间
1、字段类型(Field Type)
1、BooleanField()
2、CharField()
3、DateField()
4、DateTimeField()
5、DecimalField()
6、EmailField() #存电子邮件 - varchar
7、FloatField()
8、ImageField() #存图片路径 - varchar
ImageField(upload_to='static/***/***')
9、IntergerField()
10、URLField()
11、TextField() #存大量文本数据 - text
2、字段选项(Field Option)
1、max_length
指定数据的最大长度
在CharField()必须要设置的选项
2、default
为当前字段指定默认值
3、null
指定当前字段是否允许为空,默认值是 false
练习:
完善 FruitDay中的部分Models
1、Models :商品类型,商品,用户
2、商品类型 - GoodsType
1、类型名称 - title
2、类型图片 - picture
默认上传至: static/upload/goodstype
3、类型描述 - desc
3、商品实体 - Goods
1、商品名称 - title
2、商品价格 - price(DecimalField)
3、商品规格 - spec
4、商品图片 - picture
默认上传至:static/upload/goods
5、销售状态 - isActive(默认值为True)
4、用户实体 - Users
1、电话号码 - uphone
2、密码 - upwd
3、电子邮件 - uemail
4、用户名 - uname
5、用户状态 - isActive,默认为True
1、./manage.py migrate
执行所有应用中最新版本的数据库中间文件
2、./manage.py migrate 应用名称 版本号
执行 应用中 版本号 对应的中间文件
./manage.py inspectdb > 文件名.py
1、Entry.objects.create(属性=值,属性=值)
Entry:具体要操作的Model类
eg:
Author.objects.create(name='zsf',age=85)
2、创建一个 Models 对象,通过对象的 save() 完成增加
obj = Author(names='laoshe',age=65)
obj.save()
3、使用字典构建对象,通过 save() 完成增加
dic = {
'属性1':'值1',
'属性2':'值2',
}
obj = Entry(**dic)
obj.save()
练习:
使用三种方式,分别向 Book,Publisher 中各增加三条数据
通过 Entry.objects 调用查询接口
1、基本查询操作
语法:all()
用法:Entry.objects.all()
返回:QuerySet
eg:
Author.objects.all()
等同于:select * from index_author
返回结果:
2、查询指定列
语法:values('列1','列2',...)
用法:Entry.objects.values('列1','列2',...)
返回:QuerySet
eg:
Author.objects.values('names','age')
等同于:select name,age from index_author
注意:
values()可以用在所有的返回查询结果集的方法的后面
Author.objects.all().values('names','age')
3、排序函数
语法:order_by('列1','列2')
用法:Entry.objects.order_by('-列1','列2')
默认的排序规则是升序
如果需要降序,则在列前添加一个 "-"
eg:
1、Author.objects.order_by('age')
2、Author.objects.all().order_by('-age');
4、对条件取反
语法:exclude()
用法:Entry.objects.exclude(条件)
eg:
1、Author.objects.exclude(id=3)
select * from author where not (id=3)
2、Author.objects.exclude(id=3,age=85)
select * from author where not (id=3 and age=85)
5、根据条件查询部分行数据(重难点)
方法:filter(参数)
用法:Entry.objects.filter(参数)
1、使用 Entry 中的属性作为查询参数
多个参数的话,使用 , 隔开,映射到sql语句上,是使用 and 来进行关联的
eg:
1、Author.objects.filter(id=1)
select * from author where id=1
2、Author.objects.filter(id=1,name='莫言')
select * from author where id=1 and name='莫言'
2、通过 Field Lookup(查询表达式)完成复杂条件的构建
查询表达式:每个查询表达式都是一个独立的查询条件,可以用在所有的有查询条件的位置处
1、__exact
作用:精确查询,等值判断
用法:Entry.objects.filter(属性__exact=值)
eg:
Author.objects.filter(id__exact=1)
select * from author where id=1
2、__contains
作用:筛选出属性中包含指定关键字的记录(模糊查询)
eg:
Author.objects.filter(names__contains='ao')
select * from author where names like '%ao%'
3、__lt
作用:筛选出属性值小于指定值的记录
4、__lte
作用:筛选出属性值小于等于指定值的记录
5、__gt
作用:筛选出属性值大于指定值的记录
6、__gte
作用:筛选出属性值大于等于指定值的记录
7、__startswith
作用:筛选出以指定关键字开始的记录
8、__endswith
作用:筛选出以指定关键结尾的记录
6、查询只返回一条数据
语法:get(条件)
用法:Entry.objects.get(查询条件/表达式)
注意:
该函数只适用于 返回一条记录时使用
1、修改单个数据
1、通过 get() 得到要修改的实体对象
2、通过实体对象的属性修改属性值
3、再通过实体对象的save()保存回数据库
eg:
au = Author.objects.get(id=1)
au.names = "老舍"
au.age = 45
au.save()
2、批量修改数据
调用查询结果集的 update() 完成批量修改
Entry.objects.all().update(属性=值,属性=值)
eg:
Author.objects.all().update(age=75)
调用实体对象/查询结果集的 delete() 即可
1、删除单个对象
obj = Author.objects.get(id=1)
obj.delete()
2、删除多个对象
Author.objects.all().delete()
练习:
完成删除操作
1、点击删除链接时,删除对应的数据
http://localhost:8000/04_delete/ID
2、在对应的视图中接收参数,并将对应的author删除
作业:
1、在查询列表的基础上完成下列操作
1、点击修改的时候,将该用户的信息显示在05_au.html上
2、每个数据都用文本框显示
2、改版删除操作
1、在 Author 实体中增加一个属性 isActive,默认值为 True
2、在查询列表中,点击删除时,将要删除的用户的isActive更改为False
3、查询所有数据的时候,只查询isActive为True的用户并显示在模板上
1、转发(略)
2、重定向
1、什么是重定向
重新向新的访问地址发送请求(服务器端)
2、语法
from django.http import HttpResponseRedirect
return HttpResponseRedirect(url)
更新Author表中所有人的年龄,都+10岁
update index_author set age=age+10
错误写法:
Author.objects.all().update(age=age+10)
1、作用
在执行操作中,获取某列的值时使用
2、语法
F('列名')
from django.db.models import F
Author.objecs.all().update(age=F('age')+10)
Author.objects.filter(id=1,age=35)
select * from author where id=1 and age=35
作用:在查询条件中,可以完成或(or)的操作
语法:
from django.db.models import Q
Q(表达式)|Q(表达式)
eg:查询Author实体中,id为6或年龄大于等于70的人的信息
Author.objects.filter(Q(id=6)|Q(age__gte=70))
select * from index_author where id=6 or age>=70
1、查询
函数:raw(sql语句)
语法:Entry.objects.raw(sql)
2、增删改
def doSQL(request):
with connection.cursor() as cursor:
sql = "delete from author"
cursor.execute(sql)
return HttpResponse('...')
3、注意
raw(sql语句) 中 sql包含聚类函数如:count、sum、mix、max等,必须使用ORM原生函数,如:StatisticsData.objects.all().aggregate(Sum("daily_count"))
登录地址:http://localhost:8000/admin
创建后台管理员:
./manage.py createsuperuser
Username:输入用户名,默认为 tarena
Email Address:电子邮件
Password:密码
Password(again):重复密码
1、在应用中的 admin.py 中注册要管理的实体类
1、admin.py
作用:注册需要管理的Models,只有在此注册的Models才允许被管理
2、注册Models
from .models import *
admin.site.register(Entry)
admin.site.register(Entry)
2、修改 models.py 处理显示内容
1、在models.py中 为各个 class 追加
def __str__(self):
return self.属性名
2、通过 Models 类的内部类 Meta 定义每个类的展现形式
class Author(models.Model):
... ...
class Meta:
1、db_table
指定该实体类对应到的表的名称
2、verbose_name
定义当前实体类在后台管理的列表页中的名称(单数形式)
3、verbose_name_plural
效果同上,是复数形式
4、ordering
指定实体数据列表页中的排序规则
取值是一个列表,默认按升序排序,降序则需要手动添加 负号
练习:
1、在后台管理列表页中,每个对象都要展现他们对应的名称
2、修改 Publisher 的 Meta
1、更改表名为 publisher
2、修改其展示名称为 出版社
3、修改 Book 的Meta
1、更改表名为 book
2、修改其展示名称为 书籍
3、指定排序 - 按照出版时间降序排序
1、在 admin.py 中创建高级管理类
1、定义 EntryAdmin,继承自admin.ModelAdmin
class AuthorAdmin(admin.ModelAdmin):
pass
2、注册高级管理类
admin.site.register(Entry,EntryAdmin)
admin.site.register(Author,AuthorAdmin)
2、定制高级管理信息
1、list_display
作用:指定在 列表页中 能够显示的字段们
取值:由属性名称组成的元组或列表
eg:
list_display=['names','age','email']
2、list_display_links
作用:指定在列表页中也能链接到详情页的字段们
取值:由属性名称组成的元组或列表
注意:取值必须出现在list_display的取值中
3、list_editable
作用:指定在列表页中就允许被编辑的字段们
取值:由属性名称组成的元素或列表
注意:取值不能出现在list_display_links,但必须出现在list_display中
4、search_fields
作用:添加允许被搜索的字段们
取值:由属性名称组成的元组或列表
5、list_filter
作用:在列表的右侧增加过滤器实现快速筛选
取值:由属性名称组成的元组或列表
6、date_hierarchy
作用:在列表页的顶端增加一个时间选择器。取值必须是DateField或DateTimeField的值
7、fields
作用:在详情页面中,指定显示哪些字段并按照什么样的顺序显示
取值:由属性名称组成的元组或列表
8、fieldsets
作用:在详情页中,对字段们进行分组显示
注意:fieldsets 与 fields 不能共存
语法:
fieldsets = (
#分组1
(
'分组名称',{
'fields':('属性1','属性2'),
'classes':('collapse',),
}
),
)
练习:
为 publisher 增加高级管理功能
1、在列表页中显示,name,address,city,website属性
2、address 和 city 是可编辑的
3、右侧增加过滤器,允许按照 address 和 city进行筛选
4、分组显示
name,address,city为"基本选项"
country,website为可选选项并可以折叠
1、什么是一对一
A表中的一条记录只能与B表中的一条记录相关联
典型代表:一夫一妻制
数据库中实现:
A表:设置主键
B表:增加一列,并引用自A表的主键,还得增加一个唯一约束
2、语法
在关联的两个类的任何一个类中 增加:
属性 = models.OneToOneField(Entry)
3、查询
class Wife(models.Model):
...
author=models.OneToOneField(Author)
正向查询:通过wife 找 author
#1.获取 id 为1 的 Wife的信息
wife = Wife.objects.get(id=1)
#2.通过 Wife 的关联属性 author 来找Author
author = wife.author
反向查询:通过author 找 wife
#1.获取 id 为14 的 Author的信息
author=Author.objects.get(id=14)
#2.通过 author 的关联属性 wife 来找wife
wife = author.wife
wife 是Django通过OneToOneField在Author中默认增加的一个隐式属性
1、什么是一对多
A表中的一条数据可以与B表中的多条数据关联
B表中的一条数据只能与A表中的一条数据关联
如:
出版社(Publisher) 和 图书(Book)
商品类型(GoodsType) 和 商品(Goods)
2、在数据库中的体现
通过外键(Foreign Key)来体现一对多
在"多"表中增加外键(Foreign Key)对"一"表的主键进行引用
3、语法
使用 外键(Foreign Key)
在"多"的实体中,增加:
属性=models.ForeignKey(Entry)
eg:
Book(多) 和 Publisher(一)
class Book(models.Model):
... ...
publisher = models.ForeignKey(Publisher)
4、查询
Book(多) 和 Publisher(一)
class Book(models.Model):
... ...
publisher=models.ForeignKey(Publisher)
1、正向查询 - 通过Book查询Publisher
#查询id为1的书籍的信息
book = Book.objects.get(id=1)
#查询关联的publisher
publisher = book.publisher
2、反向查询 - 通过Publisher查询Book
Django会在 1 的实体中增加 关联对象_set 属性
用于查询 多 的数据
结合 Publisher 和 Book 之间关系 :
在 Publisher 中 增加了一个 book_set 属性
eg:
publisher=Publisher.objects.get(id=1)
books = publisher.book_set.all()
1、什么是多对多
A表中的一条记录可以与B表中的任意多条记录匹配
B表中的一条记录可以与A表中的任意多条记录匹配
ex:
作者 与 书籍
2、在数据库中的体现
必须创建第三张表,关联涉及到的两张表数据
3、语法
允许在任何一个实体中增加操作:
entry = models.ManyToManyField(Entry)
eg:
class Author(models.Model):
... ...
book = models.ManyToManyField(Book)
4、查询
class Author(models.Model):
... ...
book = models.ManyToManyField(Book)
1、正向查询-通过Author查询所有的Book
author = Author.objects.get(id=1)
books = author.book.all()
通过 关联属性.all() 查询所有对应数据
2、反向查询-通过Book查询所有的Author
Django中 会在Book 实体中增加一个隐式属性 author_set
book = Book.objects.get(id=1)
authors = book.author_set.all()
练习:
创建 Author 与 Publisher 的多对多的关系
并插入关联数据
1、查询 韩寒 所签约的所有出版社
2、查询 北京大学出版社 下所有的作者
1、声明类EntryManager,继承自models.Manager
在 EntryManager 中添加自定义函数
class EntryManager(models.Manager):
def 函数名(self,自定义参数列表):
... ...
return ... ...
2、使用 EntryManager 覆盖 models 类中的objects
class Entry(models.Model):
objects = EntryManager()
练习:
1、为 Author 指定自定义 objects 对象
1、查询年纪小于指定年纪的作者的信息
2、为 Book 指定自定义 objects 对象
1、查询书名中包含指定关键字的书籍的信息
1、请求(request)
1、请求起始行
2、请求消息头
3、请求主体
2、响应(response)
1、响应起始行
协议名称/版本号 响应状态码 原因短句
2、响应消息头
3、响应主体
1、什么是HttpRequest
HttpRequest,在Django中是对请求对象的封装体现。它封装了请求过程中所有的信息。在Django中,HttpRequest被化身成了request封装到视图处理函数中作为参数,在调用视图时自动传入
2、HttpRequest中的主要内容
1、request.scheme : 请求协议
2、request.body : 请求主体
3、request.path : 请求路径
4、request.get_host() : 请求主机/域名
5、request.method : 请求方法
6、request.GET : get请求方式提交的数据
7、request.POST : post请求方式提交的数据
8、request.COOKIES : cookies中的数据
作业:
完成之前的Author实体的修改操作
能够把数据再更新回数据库
解决方案:
1、在 settings.py中
删除CsrfViewMiddleWare中间件
2、在视图的处理函数上 @csrf_protect
3、在模板中