(由于笔记来自本地的Typora,图片未能上传,文章内容并不完整)
路由器配置
- 初始Django - 创建/结构/配置settings
- URL定义/视图函数
- 路由配置 path、re_path
python -m venv "名字"
#下载Django环境
pip install django == 2.2.2 -i https://pypi.douban.com/simple
#激活虚拟环境
D:\djangoProject\dj_base\Scripts\activate
# http://127.0.0.1:8000/page/1
path('page/1',views.page1_view)
#views.py 中的添加内容
def page1_view(request):
html = "这是编号为1的编号"
return HttpResponse(html)
Path转换器
# http://127.0.0.1:8000/page/3-100
path('page/<int:pg>',views.pagen_view)
##此时在views.py中需要如此写
def pagen_view(request,pg):
html="这是编号为%s的网页"%(pg)
return HttpResponse(html)
path的执行顺序是由上而下直至找到结束,并不会在找到的情况下执行
练习:小计算器
#urls.py
# http://127.0.0.1:8000/整数/操作符/整数
path('<int:n>/<str:op>/<int:m>',views.cal_view)
#views.py
def cal_view(request,n,op,m):
if op not in ['add','sub','mul']:
return HttpResponse("Your op is wrong")
result = 0
if op == 'add':
result = n+m
elif op == 'sub':
result = n-m
elif op == 'mul':
result = n*m
return HttpResponse('结果为:%s'%(result))
若只能做两位数的计算:(上面的path转换器就不够用了)
- re_path()
在URL的匹配过程中可以使用正则表达式进行精确匹配
语句:
re_path(reg,view,name = xxx)
- 正则表达式命名分组模式
(?P<name>pattern)
;匹配提取参数后用关键字传参方式传递给视图函数
#正则表达式(\d 表整数,\w+ 表多个字符)
#urls.py
# http://127.0.0.1:8000/整数2/操作符/整数2
re_path(r'^(?P<x>\d{1,2})/(?P<op>\w+})/(?P<y>\d{1,2})$')
#views.py
def cal2_view(request,x,op,y):
html = 'x:%s op:%s y:%s'%(x,op,y)
return HttpResponse(html)
练习 :http://127.0.0.1:8000/birthday/2015/12/11
#urls.py
#http://127.0.0.1:8000/birthday/年/月/日
re_path(r'^birthday/(?P<x>\d{4})/(?P<y>\d{1,2})/(?P<z>\d{1,2})$',views.birthday_view)
#http://127.0.0.1:8000/birthday/年/月/日
re_path(r'^birthday/(?P<x>\d{1,2})/(?P<y>\d{1,2})/(?P<z>\d{4})$',views.birthday_view)
#views.py
def birthday_view(request,x,y,z):
html = "生日为%s年%s月%s日"%(x,y,z)
return HttpResponse(html)
#def birthday2_view(request,z,y,x):
# html = "生日为%s年%s月%s日"%(x,y,z)
# return HttpResponse(html)
请求相应
定义:请求是指浏览器端通过协议HTTP协议发送给服务器端的数据
响应是指服务器收到接收到请求后做相应的处理后再回复给服务器端的数据
起始行>headers>body
请求方法:
GET:请求指定的页面信息,并返回实体主体
HEAD:类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
POST:指定资源提交数据进行处理请求。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改
PUT:从客户端向服务器传送的数据取代指定的文档的内容
DELETE:请求服务器删除指定的页面。
HTTP/1.1协议中预留给能够将连接改为管道方式的6
CONNECT:代理服务器。
OPTIONS:允许客户端查看服务器的性能。
TRACE:回显服务器收到的请求,主要用于测试或诊断。
COOKIES:Python字典,包含所有的cookie,键和值都为字符串 session:似于字典的对象,表示当前的会话
body:字符串,请求体的内容(POST或PUT) scheme:请求协议('http'/'https')
request.get_full_path():请求的完整路径
request.META:请求中的元数据(消息头)
-request.META['REMOTE_ADDR']:客户端IP地址
#utls.py
path('test_request',views.test_request)
#views.py
def test_request(request):
print('path info is',request.path_info)
print('method is',request.method)
print("querystring is",request.GET)
print("",request.get_full_path())
return HttpResponse('test request ok')
#在终端会输出一下信息
path info is /test_request
method is GET
querystring is <QueryDict: {'a': ['1'], 'b': ['1']}>
响应
起始行>headers>body
HTTP状态码的英文为HTTP Status Code
常见HTTP状态码:
-200-请求成功
-301-永久重定向-资源(网页等)被永久转移到其他URL
-302-临时重定向
-404-请求的资源(网页等)不存在
-500-内部服务器错误
构造函数格式:
HttpResponse(content = 响应体,content_type = 响应体数据类型,status = 状态码) 状态码默认200
作用:
向客户端浏览器返回响应,同时携带响应体内容
GET请求和POST请求
GET
:统一由视图函数接收请求,通过判断request.method区分具体请求动作
样例:
if request.method == 'GET':
#处理GET请求时的业务逻辑
elif request.method == 'POST':
#处理POST请求的业务逻辑
else:
#其他请求业务逻辑
浏览器地址栏输入URL、超链接、form表单中的method为get 产生GET请求的场景
URL格式:xxx?参数名1 = 值1 &参数名2=值2
http://127.0.0.1:8000/test_request?a=1&b=1
#urls.py
path('test_get_post',views.test_get_post)
#views.py
def test_get_post(request):
if(request.method == 'GET'):
print(request.GET['a'])
#应用:问卷调查 from get 兴趣爱好——复选框
#127.0.0.1:8000/test_get_post?a=1&a=2&a=3&a=4&a=5
print(request.GET.getlist('a'))
print(request.GET.get('c','no c'))
elif request.method == 'POST':
pass
else:
pass
return HttpResponse('--test get post is ok--')
#127.0.0.1:8000/test_get_post?a=1&b=1
POST
一般用于向服务器提交大量/隐私数据数据
#定义全局变量
POST_FROM = '''
<from method='post' action='/test_get_post'>
用户名:<input type='text' name = 'uname'>
<input type = 'submit' value = '提交'>
</from>
'''
#学习阶段出现403解决办法!!!
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
#'django.middleware.csrf.CsrfViewMiddleware',
#注释掉该行——> 'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
def test_get_post(request):
if (request.method == 'GET'):
#print(request.GET['a'])
# 应用:问卷调查 from get 兴趣爱好——复选框
# 127.0.0.1:8000/test_get_post?a=1&a=2&a=3&a=4&a=5
# print(request.GET.getlist('a'))
# print(request.GET.get('c', 'no c'))
return HttpResponse(POST_FROM)
#先GET请求进入该操作——>return POST_FROM 请求 执行下一个elif操作
elif request.method == 'POST':
#用户处理提交数据
print('uname is',request.POST['uname'])#这在命令行输出的内容
return HttpResponse('post is ok')
else:
pass
return HttpResponse('--test get post is ok--')
Django的设计模式及模板层
MVC和MTV
模板:1.是可以根据字典数据动态变化html页面
2.模板可以根据视图中传递的字典数据动态生成相应的HTML页面
模板创建:
loader方法
-
在项目下创建一个templates文件夹
-
在settings.py中TEMPLATES
'DIRS': [os.path.join(BASE_DIR,'templates')],
-
views.py中
def test_html(request): #方案1 from django.template import loader t = loader.get_template('test_html.html') html = t.render() return HttpResponse(html)
4.urls.py中
path('test_html',views.test_html)
5.在文件夹templates中建test_html.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>我是模板层的~~~~~~~</h3> </body> </html>
render()直接加载并响应模板
只在views.py中改(相对于上面的)
def test_html(request):
#方案2
from django.shortcuts import render
return render(request,'test_html.html')
视图函数与模板之间的交互
视图函数可以将python变量封装到字典中传递到模板
模板中,我们可以用变量{{变量名}}的语法 调用视图传进来的变量
def xxx_view(request):
dic = {
"变量1":"值1"
"变量2":"值2"
}
request render(request,'xxx.html',dic)
def test_html(request):
#方案2
from django.shortcuts import render
dic = {'username':'gouxiaonao','age':18}
return render(request,'test_html.html',dic)
#html文件
<h3>{{ username}}是模板层的~~~~~~~</h3>
模板层-变量
能传到模板中的 数据类型 : str, int, list数组, tuple 元组, dic 字典, func 方法, obj 类实例化的对象
在模板中使用变量法:
{{变量名}}
{{变量名. index}}
{{变量名.key}}
{{对象.方法}}
{{函数名}}
#views.py中
def test_html_param(request):
dic = {}
dic['int'] = 88
dic['str'] = 'apple'
dic['listpp'] = ['Tom','Jack','Lily']
dic['dict'] = {'a':9,'b':8}
dic['func'] = say_hi
dic['class_obj'] = Dog()
return render(request,'test_html_param.html')
def say_hi():
return 'hahaha'
class Dog:
def say(self):
return 'wowowo'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>int 是 {{ int }}</h3>
<h3>str 是 {{ str }}</h3>
<h3>lst 是 {{ listpp }}</h3>
<h3>lst.0 是 {{ listpp.0 }}</h3>
<h3>dict 是 {{ dict }}</h3>
<h3>dict['a'] 是 {{ dict.a }}</h3>
<h3>function 是 {{ func }}</h3>
<h3>class_obj 是 {{ class_obj.say }}</h3>
</body>
</html>
#urls.py文件
path('test_html_param',views.test_html_param)
三者的关系:输入http://127.0.0.1:8000/test_html_param》对应urls.py重点path》找到views中的test_html_param函数def》该函数中有一定的数据dic字典》将这些字典发送给test_html_param.html文件》html文件中使用{{}}方式直接引用dic中的数据!
模板标签
作用:将一些服务器端的功能嵌入到模板中,例如流程控制等。
{% 标签%}
{%结束标签%}
def test_if_for(request):
from django.shortcuts import render
dic = {}
dic['x'] = 10
dic['list'] = {'小米','小航','小度'}
return render(request,'test_if_for.html',dic)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试 if 和 for</title>
</head>
<body>
{% if x > 10 %}
今天ok
{% elif x < 10 %}
今天还ok
{% endif %}
{% for name in list%}
{% if forloop.first %}++++++{% endif %}
<p> {{forloop.counter}}{{name}}</p>
{% if forloop.last %} ====={% endif %}
{%empty%}
当前无数据
{%endfor%}
</body>
</html>
练习:if标签计算器
def mycal(request):
if request.method == "GET":
return render(request,'mycal.html')
elif request.method == 'POST':
x = int(request.POST['x'])
y = int(request.POST['y'])
op = request.POST['op']
result = 0;
if op == 'add':
result = x+y
elif op == 'sub':
result = x-y
elif op == 'mul':
result = x*y
elif op == 'div':
result = x/y
return render(request,'mycal.html',locals())
<form action="/mycal" method="post">
<input type="text" name = "x" value = "{{x}}">
<select name = "op">
<option vaule = "add"{% if op == "add" %} selected {% endif %}>+加</option>
<option value = "sub" {% if op == 'sub' %} selected {% endif %} >-减 </option>
<option value = "mul" {% if op == 'mul' %} selected {% endif %} >-乘 </option>
<option value = "sub" {% if op == 'div' %} selected {% endif %} >-除 </option>
</select>
<input type="text" name = "y" value = "{{y}}">=<span>{{ result }}</span>
<div><input type = "submit" value = "开始计算"></div>
</form>
模板层-过滤器
过滤器
定义:在变量输出时对变量的值进行处理
lower将字符串转换为全部小写
upper 转换成大写
safe 默认不对变量内的字符串进行html转义(加safe后可执行html代码)
add: "n" 将value的值增加n
truncatechars:'n'如果字符串字符多于指定的字符数量,那么会被截断。截断的子字符串将以可翻译的省略号序列("...")结尾
<h3>str 是 {{ str|lower }}</h3>
模板的继承
模板继承可是父模板的内容重用,子模板直接继承父模板的全部内容并可以覆盖父模板中相应的块。
- 定义父模板中的块block标签
- 标识出哪些子模块中是允许被修改的
- block标签:在父模板中定义,可以在子模板中覆盖
注意:模板继承时,服务器端的动态内容无法继承
子模板中:
- 继承extends 标签
{%extends 'base.html'%}
-
子模板重写父模板中的内容块
{%block block_name%}
#这里写可更改的内容
{% endblock %}
def base_view(request):
return render(request,'base.html')
def music_view(request):
return render(request,'music.html')
def sport_view(request):
return render(request,'sport.html')
//父类html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
{% block mytitle %}
<title>主页</title>
{% endblock %}
</head>
<body>
<a href = "/music_index">音乐频道</a>
<a href = "/sport_index">体育频道</a>
<br>
{% block info %}
这是主页
{% endblock %}
<br>
<h3>有问题请</h3>
</body>
</html>
//子类html
{% extends 'base.html' %}
{% block mytitle %}
<title>音乐频道</title>
{% endblock %}
{% block info%}
欢迎来到音乐频道
{% endblock %}
url反向解析
代码中url出现位置
一、
1. <a href = 'url'>超链接</a>
#点击后 页面跳转至url
2.<form action = 'url' method = 'post'>
#form表单中的数据 用post方法提交至url
</form>
二、
视图函数中-302跳转 HttpResPonseRedirect('url')
将用户地址栏中地址跳转到url
书写规范
相对地址:
"/music_index" 1.有'/'开头的相对地址,地址ip+端口,http://127.0.0.1:8000/page/3。http://127.0.0.1:8000/page/1。2.没有'/'开头的相对地址,http://127.0.0.1:8000/page/3,“test_url_result,”http://127.0.0.1:8000/page/test_url_result
def test_url(request):
return render(request,'test_url.html')
def test_url_result(request):
return HttpResponse('---test url res is ok')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试URL</title>
</head>
<body>
<a href = "http://127.0.0.1:8000/test_url_result">绝对地址</a>
<a href = "/test_url_result">带'/'的相对地址</a>
<a href = "test_url_result">不带'/'的相对地址</a>
</body>
</html>
#urls.py
#http://127.0.0.1:8000/test/url
path("test/url",views.test_url),
path("test_url_result",views.test_url_result)
反向解析
url反向解析是指视图或模板中,用path定义的名称来动态查找或计算出相应的路由
path函数的语法:path(route,views,name = "别名")
模板中:{% url 'page' '400' %}
def test_url_result(request,age):
return HttpResponse('---test url res is ok')
path("test_url_result/<int:age>",views.test_url_result,name = 'tr')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试URL</title>
</head>
<body>
<a href = "http://127.0.0.1:8000/test_url_result">绝对地址</a>
<a href = "/test_url_result">带'/'的相对地址</a>
<a href = "test_url_result">不带'/'的相对地址</a>
<br>
<a href = "{% url 'tr' '100'%}">url反向解析版本</a>
</body>
</html>
在views.py中
def test_url_result(request,age):
#302 跳转
from django.urls import reverse
url = reverse('base_index')
return HttpResponseRedirect(url)
#return HttpResponse('---test url res is ok')
#注意:要在首部 from django.http import HttpResponseRedirect
#urls.py
path('base_index',views.base_view,name = 'base_index'),
#加一个别名!!!方便调用
静态文件
静态文件:图片、css、js、音频、视频
#file:setting.py
#保存的是静态文件在服务器端的存储位置“BASE_DIR”
STATICFILES_DIRS = (
os.path.join(BASE_DIR,"static"),
)
方法一:
<body>
<img src="http://127.0.0.1:8000/static/image/46dc90c5-2195-44fd-9d64-c4b54f7a831a.jpeg" alt="ji" width="200px" height="200px">
<img src="/static/image/46dc90c5-2195-44fd-9d64-c4b54f7a831a.jpeg" alt="ji" width="200px" height="200px">
</body>
方法二:
{% load static %}
<img src="{% static 'image/test.jpg'%}" width="200px" height="200px">
#setting.py中
STATIC_URL = '/static/'
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
#views.py中
path('test_static',views.test_static),
#urls.py中
from django.shortcuts import render
def test_static(request):
return render(request,'test_static.html')
django应用及分布式路由
应用:
在Django项目中是一个独立的业务模块,可以包含自己的路由、视图、模板、模型。
创建应用
- 用manage.py 中的子命令startapp创建引用文件夹
python manage.py startapp music
- 在setting.py的INSTALLED_APPS列表中配置安装此应用
分布式路由:
可以在主路由配置文件(urls.py)中不处理用户具体路由,主路由有配置问价的可以做请求的分发(分布式请求处理)。具体的请求可以由各自的应用来处理。
添加分布路由步骤
#主路由urls.py中
from django.urls import path, include
path('music/',include('music.urls'))
#music.urls中
from django.urls import path
from . import views
urlpatterns = [
# http://127.0.0.1:8000/music/index
path('index',views.index_view)
]
#music.views中
from django.http import HttpResponse
from django.shortcuts import render
# Create your views here.
def index_view(request):
return HttpResponse("这是音乐频道");
应用下的模板
应用内部可以配置模板目录
-
应用下手动创建templates文件夹
-
setting.py中开启 应用模板功能
- TEMPLATE配置项中的'APP_DIRS'值为True即可
应用下templates 和 外层templates都存在时,django得查找模板规则
- 优先查找外城templates目录下的模板
- 按INSTALLED_APPS配置下的应用顺序 逐层查找(如果在templates中创建目录,则可以避免因顺序导致的错乱)
def news_index(request):
# return HttpResponse("这是新闻界面")4
return render(request, 'news/index.html')
#这是在templates目录下创建news文件夹 放入index.html应用方法
模板层及ORM介绍
配饰mysql 服务
1. 自己电脑上需要先安装mysql (下载地址)https://dev.mysql.com/downloads/mysql/
2.配置环境变量及其后面步骤(https://blog.csdn.net/weixin_42869365/article/details/83472466)
运行MySQL在pycahrm中
1.首先需要在终端中在mysql里创建项目
create database mysite3,需要创建 数据库后才能执行
再 看下面
创建 数据库项目
MySQL服务改密码操作
启动服务
net start mysql
安装mysqlclient
创建数据库
进入mysql数据库执行(mysql -u root -p)
creat database 数据库名 default charset utf8
通常数据库名跟项目名保持一致
setting.py里进行数据库的配置
修改DATABASE配置项的内容,由sqlite3变为mysql
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME':'mysite3',
'USER':'root',
'PASSWORD':'123456',//这个需要和你创建的mysql密码一致
'HOST':'127.0.0.1',
'PORT':'3306'#端口号
}
}
- 什么是模型:模型是一个python类,它是由django.models.Model派生出的子类
- 一个模型类代表数据库中的一张数据表
- 模型类中每一个类属性都代表数据库中的一个字段。
- 模型是数据交互的接口,是代表和操作数据库的方式和方法
ORM:
即对象关系映射,对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。它允许使用类和对象对数据库进行操作,从而避免通过SQL语句操作数据库。
作用:
-
建立模型类和表之间的对应关系,允许我们通过面向对象方式来操作数据库。
-
根据设计的模型类生成数据库中的表格
-
通过简单的配置就可以进行数据库的切换
创建一个模型
#1、创建应用
#2、在应用中models.py中编写模型类
#3、创建模型类
from django.db import models
class 模型类名(models.Model):
字段名 = models.字段类型(字段选项)
#实操
from django.db import models
# Create your models here.
class Book(models.Model):
title = models.CharField('书名',max_length = 50,default='')
price = models.DecimalField('价格',max_digits=7,decimal_places=2)
#4、再执行,生成相应的文件,并迁移同步(终端中)
python manage.py startapp bookstore#创建应用
#执行 命令,迁移数据到Mysql中
python manage.py makemigrations
python manage.py migrate
添加新字段
解决:模型类中添加 对应 类属性
执行数据库迁移
模型类——字段类型
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():日期时间
FloatField():double类型
DecimalField():小数,跟前相关的。max_digits位数总数,decimal_places小数点后的数字数量
EmailFIeld():varcahr, 存邮箱
IntegerField():int 编程语言和数据库中使用整数
ImageField():varchar(100)图片的路径
TextField():longtext表示不定长的字符数据
ORM-基础字段及选项2
模型类-Meta类(内部类)
from django.db import models
# Create your models here.
class Book(models.Model):
title = models.CharField('书名',max_length = 50,default='')
price = models.DecimalField('价格',max_digits=7,decimal_places=2)
class Meta:
db_table = 'book'
ORM-基本操作-创建数据
数据库中django_migrations 表记录了migrate的"全过程",项目各应用中的migrate文件应与之对应,否则migrate会报错
管理对象
进入 Django Shell 交互环境 python manage.py shell
方案一:添加表的内容
方案二:
ORM-查询操作
查询语句
数据库 的查询需要使用管理器对象进行
通过MyModel.objects管理器方法调用查询方法
all():查询全部记录,返回QuerySet查询对象
get():查询符合条件的单一记录
filter():查询符合条件的多条记录
exclude():查询符合条件之外的全部记录
(首先需要进入 到 shell 中)
from bookstore.models import Book
books = Book.objects.all(); // 等同于 select * from table
for book in books:
print("书名",book.title,"出版社",book.pub)
在模型类中定义__str__
方法
def __str__(self):
return '%s%s%s%s' % (self.title,self.pub,self.price,self.market_price)
//使用方法
Values('列1','列2')
MyModel.objects.values(...) 输入 查询值
字典
Values-list
元组
order_by() 默认是按升序,若是 降序 加"-"负号
实操项目
#djangoProject1\urls.py
path('bookstore/',include('bookstore.urls'))
#bookstore\urls.py
from django.urls import path
from . import views
urlpatterns = [
path('all_book',views.all_book)
]
#bookstore\views.py
from django.shortcuts import render
from .models import Book
# Create your views here.
def all_book(request):
all_book = Book.objects.all()
return render(request,'bookstore/all_book.html',locals())
#bookstore/templates/bookstore/all_book.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>查看所有书籍</title>
</head>
<body>
<table border="1">
<tr>
<th>id</th>
<th>title</th>
<th>pub</th>
<th>price</th>
<th>market</th>
<th>op</th>
</tr>
<tr>
{% for book in all_book %}
<tr>
<td>{{ book.id}}</td>
<td>{{book.title}}</td>
<td>{{ book.pub }}</td>
<td>{{ book.price }}</td>
<td>{{ book.market_price }}</td>
<td>
<a href="">更新</a>
<a href="">删除</a>
</td>
</tr>
{% endfor %}
</tr>
</table>
</body>
</html>
条件查询
MyModels.objects.filter(),返回值:QuerSet容器对象
from bookstore.models import
books = Book.objects.filter(pub = '清华大学出版社')
for book in books:
print("书名",book.title)
.exclude(条件):返回不包含 此条件的 全部 数据集
.get(条件):返回满足条件的唯一一条数据(如果 查询结果 多于一条 或没有数据,则会报错!)
非等值查询——查询谓词
__exact:等值匹配
Author.objects.filter(id__exact = 1)
等同于 select * from author where id = 1
__contains:包含指定值
__startswith:以xxx开始
__endswith:以xxx结束
__gt:大于指定值
__gte:大于等于
__lt:小于
__lte:小于等于
__in:查找数据是否在指定范围内
__range:查找数据是否在指定的区间范围内
更新操作
单个数据修改
1.差 -通过get() 得到要修改的实体对象
2.改 -通过 对象.属性 的方式修改数据
3.保存 -通过 对象.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)
实操:制作一个能 反馈的 图书管理系统
删除操作
单个数据删除
方法:找到——再删除
try:
auth = Author.objects.get(id = 1)
auth.delete()
except:
print(删除失败)
批量删除
方法:找到符合查询结果集中满足条件的全部QuerSet查询集合对象
auths = Author.objects.filter(age__gt = 65)
auths.delete()
伪删除
添加布尔类型字段(is_active),默认为true
is_active = models.BooleanField('是否活跃',default=True)
mysql> select * from book;
+----+--------+-------+--------------+----------------+-----------+
| id | title | price | market_price | pub | is_active |
+----+--------+-------+--------------+----------------+-----------+
| 1 | python | 26.00 | 25.00 | 浙江工商大学 | 1 |
| 2 | Django | 19.00 | 12.00 | 杭州商学院 | 1 |
| 3 | JQuery | 19.00 | 9.90 | 机械工业出版社 | 1 |
| 4 | Linux | 70.00 | 78.00 | 清华大学出版社 | 1 |
+----+--------+-------+--------------+----------------+-----------+
4 rows in set (0.00 sec)
实操:
#views.py
def delete_book(request):
#通过获取字符串 book_id 拿到要删除的book的id
book_id = request.GET.get('book_id')
if not book_id:
return HttpResponse('---请求异常')
try:
book = Book.objects.get(id = book_id,is_active=True)
except Exception as e:
print('---delete book get error %s'%(e))
return HttpResponse('---The book id is error')
#将其is_active改成False
book.is_active = False #这里就是在对数据库里的数据进行操作了
book.save()#改后记得 保存!!!
# 302跳转至all_boo
#url.py
from django.urls import path
from . import views
urlpatterns = [
path('all_book',views.all_book),
path('update_book/<int:book_id>',views.update_book),
path('delete_book',views.delete_book),
]
#all_book.html
<a href="/bookstore/update_book/{{ book.id }}">更新</a>
<a href="/bookstore/delete_book?book_id={{ book.id }}">删除</a>
F对象和Q对象
F对象:
一个F对象代表数据库中某条记录的字段信息
作用:通常是对数据库中的字段值再不获取的情况下进行操作
用于类属性(字段)之 间的比较
from django.db.models import F
F('列名')
实例:更新Book实例中所有的零售价涨10元
Book.objects.all().update(market_price = F('market_price') + 10)# += 10
Q:
当获取查询结果集 使用复杂的逻辑或 |、逻辑非 ~ 等操作时可以借助于Q对象进行操作
需要 导入 django.db.models
例如:想要找出定价低于20元 或 清华大学出版社的全部书籍,可以写成
Book.objects.filter(Q(price__lt = 20) | Q(pub = "清华大学出版社"))
聚合查询和原生数据库操作
聚合查询
对一个数据表中的一个字段的数据进行部分或全部进行统计查询
整表聚合
分组聚合
原生数据库操作
查询:使用MyModel.objects.raw()进行 数据库查询操作查询
语法:MyModel.objects.raw(sql 语句,拼接参数)
返回值:RawQuerySet 集合 对象【只支持基础操作,如循环】
books = models.Book.objects.raw('select * from bookstore_book')
for book in books:
print(book)
*使用原生语句时小心 SQL注入
admin后台管理
admin后台管理1
admin2
注册自定义模型类
#在admin.py文件中添加自己的 后台模板
from django.contrib import admin
from .models import Book
# Register your models here.
admin.site.register(Book)
模型管理器类
作用: 为后台管理界面添加便于操作的新功能
说明: 后台管理器类须继承自django.contrib.admin里的ModelAdmin类
#在admin.py文件中添加自己的 后台模板
from django.contrib import admin
from .models import Book
# Register your models here.
class BookManager(admin.ModelAdmin):
list_display = ['id','title','pub','price']
#控制list_display中的字段,哪些可以链接到
list_display_links = ['title']
#添加过滤器
list_filter = ['pub']
#添加搜索框[模糊查询]
search_fields = ['title']
#添加可在列表页编辑的字段
list_editable = ['price']
admin.site.register(Book,BookManager)
关系映射(关系)
一对一模型
一对多、多对多
实操:
一对多模型
:一个学校有多个班级,一个班级有多个学生,一本图书只能属于一个出版社,一个出版社允许出版多本图书。 一对多:需要确定具体角色,多表上设置外键
class A(models.Model):
class B(models.Model):
属性 = models.ForeignKey('***',on_delete = xx)
#ForeignKey 必须指定为 on_delete模型
#实操 otm - models.py 中
from django.db import models
# Create your models here.
class Publisher(models.Model):
name = models.CharField('出版社名称',max_length=50);
class Book(models.Model):
title = models.CharField('书名',max_length=11)
publisher = models.ForeignKey(Publisher,on_delete=models.CASCADE)
创建数据值:
多对多模型
#创建
from django.db import models
# Create your models here.
class Author(models.Model):
name = models.CharField('姓名',max_length=11)
class Book(models.Model):
title = models.CharField('书名',max_length=11)
author = models.ManyToManyField(Author)
创建数据
from mtm.models import *
>>> a1 = Author.objects.create(name = '孙老师')
>>> b1 = a1.book_set.create(title = 'python训练书')
>>>
>>>
>>> a2 = Author.objects.create(name = '刘老师')
>>> b1
<Book: Book object (1)>
>>> a2.book_set.add(b1)
>>>
cookies 和 session
cookies 和 session 都是为了保持对话状态而诞生的两个存储技术
cookies
:是保存在客户端浏览器上的存储空间。在浏览器上以键-值队形式(ASCII码值)存放。且都带有生命周期。cookies中的数据都是按域存储隔离的,不同的域之间无法访问。cookies的内部的数据会在每次访问此网络时都会携带到服务器端,如果cookies过大会降低相应速度。
path('set_cookies',views.set_cookies),
def set_cookies(request):
resp = HttpResponse("set cookies is ok")
resp.set_cookie('uuname','gxn',500)
return resp
获取
path('get_cookies',views.get_cookies),
def get_cookies(request):
value = request.COOKIES.get('uuname')
return HttpResponse('value is %s'%(value))
session
在服务器上开辟一段空间用于保存浏览器和服务器交互时的重要诗句。
实现方式:使用session需要在浏览器客户端启动cookie,且在cookie存储sessionid
每个客户端都可以在服务器端有一个独立的Session
注意不同的请求之间不会共享这个数据,与请求者一一对应。
session的使用
session对于象是一个类似于字典的SessionStore类型的对象,可以用类似于字典的方式进行操作
session能够存储如字符串,整型,字典,列表等
1、保存session的值到服务器
request.session['KEY'] = VALUE
2、获取session的值
value = request.session['KEY']
value = request.session.get('KEY',默认值)
3、删除session
del request.session['KEY']
标签:python,py,request,笔记,Django,models,html,test,path From: https://www.cnblogs.com/Hygge1024/p/18060825