发布时间:2025-12-10 11:44:36 浏览次数:5
课程特点:
查看已安装的版本
>>> import django>>> print(django.VERSION)(1, 11, 8, 'final', 0)安装
Django的卸载
$ pip3 uninstall django
Django 的开发环境
BASE_DIR
用于绑定当前项目的绝对路径(动态计算出来的), 所有文件都可以依懒此路径
用于配置Django项目的启用模式, 取值:
True 表示开发环境中使用 调试模式(用于开发中)
False 表示当前项目运行在生产环境中(不启用调试)
ALLOWED_HOSTS
设置允许访问到本项目的网络地址列表,取值:
python3 manage.py runserver 0.0.0.0:5000 # 指定网络设备所有主机都可以通过5000端口访问(需加ALLOWED_HOSTS = ['*'])
指定当前项目中安装的应用列表
用于注册中间件
用于指定模板的配置信息
用于指定数据库的配置信息
用于指定语言配置
取值:
英文 : "en-us"
中文 : "zh-Hans"
用于指定当前服务器端时区
取值:
世界标准时间: "UTC"
中国时区 : "Asia/Shanghai"
用于配置根级 url 配置 ‘mysite1.urls’
如:
ROOT_URLCONF = 'mysite1.urls'
注: 此模块可以通过 from django.conf import settings 导入和使用
url 即统一资源定位符 Uniform Resource Locator
作用:
说明:
URL的一般语法格式为:
https://www.djangoproject.com/download/
protocol :// hostname[:port] / path [?query][#fragment]如:
http://tts.tmooc.cn/video/showVideo?meuId=657421&version=AID201908#s说明:
用函数创建的视图
视图函数是用于接收一个浏览器请求并通过HttpResponse对象返回数据的函数。此函数可以接收浏览器请求并根据业务逻辑返回相应的内容给浏览器
视图处理的函数的语法格式:
def xxx_view(request[, 其它参数...]):return HttpResponse对象参数:
示例:
视图处理函数 views.py
# file : <项目名>/views.pyfrom django.http import HttpResponsedef page1_view(request):html = "<h1>这是第1个页面</h1>"return HttpResponse(html)优点:可以直接匹配get,post,head等请求方式
如果平常的用FBV的话就需要匹配用if—elif的方式来匹配访问方式,这种方式往往显得很笨拙
views.py
# FBV模式def home(request):if request.method == 'GET':xxxxelif request.method == 'POST':XXXurls.py
from django.urls import path,includefrom index import viewsurlpatterns = [# FBV模式path('',views.index_home)]views.py
# CBV模式class Index_home(View):def get(self,request):return HttpResponse('这是get主页')def post(self,request):return HttpResponse('这是post主页')urls.py
from django.urls import path,includefrom index import viewsurlpatterns = [# FBV模式# path('',views.index_home)# CBV模式path('',views.Index_home.as_view())]path函数的第一个参数为路由地址名,第二个参数为views的函数名
函数 path() 具有四个参数,两个必须参数:route 和 view,两个可选参数:kwargs 和 name。现在,是时候来研究这些参数的`含义了。
route 是一个匹配 URL 的准则(类似正则表达式)。当 Django 响应一个请求时,它会从 urlpatterns 的第一项开始,按顺序依次匹配列表中的项,直到找到匹配的项。
这些准则不会匹配 GET 和 POST 参数或域名。例如,URLconf 在处理请求 https://www.example.com/myapp/ 时,它会尝试匹配 myapp/ 。处理请求 https://www.example.com/myapp/?page=3 时,也只会尝试匹配 myapp/
view当 Django 找到了一个匹配的准则,就会调用这个特定的视图函数,并传入一个 HttpRequest 对象作为第一个参数,被“捕获”的参数以关键字参数的形式传入
kwargs任意个关键字参数可以作为一个字典传递给目标视图函数
name为你的 URL 取名能使你在 Django 的任意地方唯一地引用它,尤其是在模板中。这个有用的特性允许你只改一个文件就能全局地修改某个 URL 模式。
定义
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pxiZ6lVJ-1683969713205)(…/assets/image-20220308134517864_1646837814760_0.png)]
# 例子 匹配127.0.0.1/int/str/int 第一个参数为任意整型,第二个参数为任意字符型,第三个参数为任意整型path('<int:a>/<str:sml>/<int:b>',views.cal_view),类型分类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YYmyKwne-1683969713206)(…/assets/image-20220308134802884_1646837839971_0.png)]
根据HTTP标准,HTTP请求可以使用多种请求方法。
HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法(最常用)
HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
HTTP1.1 请求详述
| 1 | GET | 请求指定的页面信息,并返回实体主体。 |
| 2 | HEAD | 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头 |
| 3 | POST | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。 |
| 4 | PUT | 从客户端向服务器传送的数据取代指定的文档的内容。 |
| 5 | DELETE | 请求服务器删除指定的页面。 |
| 6 | CONNECT | HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。 |
| 7 | OPTIONS | 允许客户端查看服务器的性能。 |
| 8 | TRACE | 回显服务器收到的请求,主要用于测试或诊断。 |
django的view.py的每个视图函数的形参里面都有一个request,这就是httpRequest对象,httpRequest有很多属性和方法供我们服务端使用,我们可以从中简单的得到客户端发来的请求信息
常用的方法和属性如下
视图函数的第一个参数是HttpRequest对象
服务器接收到http协议的请求后,会根据请求数据报文创建HttpRequest对象
HttpRequest属性
当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头用以响应浏览器的请求。
HTTP状态码的英文为HTTP Status Code。
下面是常见的HTTP状态码:
HTTP状态码分类
HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。HTTP状态码共分为5种类型:
| 1** | 信息,服务器收到请求,需要请求者继续执行操作 |
| 2** | 成功,操作被成功接收并处理 |
| 3** | 重定向,需要进一步的操作以完成请求 |
| 4** | 客户端错误,请求包含语法错误或无法完成请求 |
| 5** | 服务器错误,服务器在处理请求的过程中发生了错误 |
视图函数的返回的一个函数
HttpResponse详解
构造函数格式:
HttpResponse(content=响应体, content_type=响应体数据类型, status=状态码)
作用:
collapsed:: true
参数:
collapsed:: true
content:表示返回的内容。
status_code:返回的HTTP响应状态码(默认为200)。
content_type:指定返回数据的的MIME类型(默认为"text/html")。浏览器会根据这个属性,来显示数据。如果是text/html,那么就会解析这个字符串,如果text/plain,那么就会显示一个纯文本。
常用的Content-Type如下:
'application/xml'(xml文件)
> 注: 关键字MIME(Multipurpose Internet Mail Extensions)是指多用途互联网邮件扩展类型。HttpResponse 子类
| HttpResponseRedirect | 重定响 | 301 |
| HttpResponseNotModified | 未修改 | 304 |
| HttpResponseBadRequest | 错误请求 | 400 |
| HttpResponseNotFound | 没有对应的资源 | 404 |
| HttpResponseForbidden | 请求被禁止 | 403 |
| HttpResponseServerError | 服务器错误 | 500 |
GET请求方式中可以通过查询字符串(Query String)将数据传递给服务器
URL 格式: xxx?参数名1=值1&参数名2=值2...
服务器端接收参数
判断 request.method 的值判断请求方式是否是get请求
if request.method == 'GET':处理GET请求时的业务逻辑else:处理其它请求的业务逻辑获取客户端请求GET请求提交的数据
语法
request.GET['参数名'] # QueryDictrequest.GET.get('参数名','默认值') # 类似于字典的request.GET.getlist('参数名')# mypage?a=100&b=200&c=300&b=400# request.GET=QueryDict({'a':['100'], 'b':['200','400'], 'c':['300']})# a = request.GET['a']# b = request.GET['b'] # Error能够产生get请求方式的场合
地址栏手动输入, 如: http://127.0.0.1:8000/mypage?a=100&b=200
<a href="地址?参数=值&参数=值">
form表单中的method为get
<form method='get' action="/user/login">姓名:<input type="text" name="uname"></form>一般查询字符串的大小会受到浏览器的的限制(不建议超过2048字节)
练习:
练习:
客户端通过表单等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 请求的响应使用post方式接收客户端数据
取消csrf验证,否则Django将会拒绝客户端发来的POST请求
取消 csrf 验证
删除 settings.py 中 MIDDLEWARE 中的 CsrfViewsMiddleWare 的中间件
```python```pythonMIDDLEWARE = [ ..# 'django.middleware.csrf.CsrfViewMiddleware',...]```MTV 代表 Model-Template-View(模型-模板-视图) 模式。这种模式用于应用程序的分层开发
模板传参是指把数据形成字典,传参给模板,为模板渲染提供数据
在模板中使用变量语法
{{ 变量名 }}
{{ 变量名.index }} list.0
{{ 变量名.key}} dict[‘key’] dict.key
{{ 对象.方法 }}
{{ 函数名 }}
练习
写一个简单的计算器页面,能够在服务端进行简单加减乘除计算
form中的action属性 -> 此次提交的地址
ex: action=‘/mycal’ -> 提交地址为当前浏览器地址栏的ip+端口+ action, 即 http://127.0.0.1:8000/mycal
参考代码
<form action='/mycal' method='POST'><input type='text' name="x" value="1"><select name='op'><option value="add" > +加 </option><option value="sub" > -减 </option><option value="mul"> *乘 </option><option value="p"> /除 </option></select><input type='text' name="y" value="2"> = <span>3</span><p><input type="submit" value='开始计算'><p></form>作用
将一些服务器端的功能嵌入到模板中
标签语法
{% 标签 %}...{% 结束标签 %}if 标签
{% if 条件表达式1 %}...{% elif 条件表达式2 %}...{% elif 条件表达式3 %}...{% else %}...{% endif %}if 标签里的布尔运算符
if 条件表达式里可以用的运算符 ==, !=, <, >, <=, >=, in, not in, is, is not, not、and、or
在if标签中使用实际括号是无效的语法。 如果您需要它们指示优先级,则应使用嵌套的if标记。
locals函数的使用
locals() 返回当前函数作用域内全部局部变量形成的字典。
for 标签
| forloop.counter | 循环的当前迭代(从1开始索引) |
| forloop.counter0 | 循环的当前迭代(从0开始索引) |
| forloop.revcounter | 循环结束的迭代次数(从1开始索引) |
| forloop.revcounter0 | 循环结束的迭代次数(从0开始索引) |
| forloop.first | 如果这是第一次通过循环,则为真 |
| forloop.last | 如果这是最后一次循环,则为真 |
| forloop.parentloop | 当嵌套循环,parentloop 表示外层循环 |
作用
在变量输出时对变量的值进行处理
您可以通过使用 过滤器来改变变量的输出显示。
{{ 变量 | 过滤器1:参数值1 | 过滤器2:参数值2 … }}
常用的过滤器
| lower | 将字符串转换为全部小写。 |
| upper | 将字符串转换为大写形式 |
| safe | 默认不对变量内的字符串进行html转义 |
| add: “n” | 将value的值增加 n |
| truncatechars:‘n’ | 如果字符串字符多于指定的字符数量,那么会被截断。 截断的字符串将以可翻译的省略号序列(“…”)结尾。 |
| … |
文档参见:
https://docs.djangoproject.com/en/1.11/ref/templates/builtins/
模板继承可以使父模板的内容重用,子模板直接继承父模板的全部内容并可以覆盖父模板中相应的块
定义父模板中的块 block标签
标识出哪些在子模块中是允许被修改的
block标签:在父模板中定义,可以在子模板中覆盖
{% block block_name %}定义模板块,此模板块可以被子模板重新定义的同名块覆盖{% endblock block_name %}继承模板 extends 标签(写在模板文件的第一行)
子模板继承语法标签
子模板 重写父模板中的内容块
{% block block_name %}子模板块用来覆盖父模板中 block_name 块的内容{% endblock block_name %}重写的覆盖规则
注意
参考文档
https://docs.djangoproject.com/en/1.11/ref/templates/
模板的继承示例:
url 反向解析是指在视图或模板中,用为url定义的名称来查找或计算出相应的路由
url 函数的语法
url() 的name关键字参数
作用:
在模板中通过别名实现地址的反向解析
{% url '别名' %}{% url '别名' '参数值1' '参数值2' %}练习:
写一个有四个自定义页面的网站,对应路由:/ 主页/page1 页面1/page2 页面2/page3 页面3功能: 主页加 三个页面的连接分别跳转到一个页面,三个页面每个页面加入一个链接用于返回主页url反向解析在django的视图函数的应用
实际用法
先在路由函数中取别名,然后在视图函数中利用reverse函数进行反向解析
什么是静态文件
静态文件配置
配置静态文件的访问路径
https://oimagea1.ydstatic.com/image?id=-5337101211608292607&product=adpublish&w=640&h=480&sc=0&rm=2&gsb=0&gsbd=60
配置静态文件的存储路径 STATICFILES_DIRS
示例:
# file: setting.pySTATICFILES_DIRS = (os.path.join(BASE_DIR, "static"),)访问静态文件
使用静态文件的访问路径进行访问
访问路径: STATIC_URL = ‘/static/’
示例:
<img src="/static/images/lena.jpg"><img src="http://127.0.0.1:8000/static/images/lena.jpg">通过 {% static %}标签访问静态文件
创建步骤
创建应用的子命令
Django应用的结构组成
配置安装应用
在 settings.py 中配置应用, 让此应用能和整个项目融为一体
# file : settings.py INSTALLED_APPS = [... ...,'自定义应用名称']如:
INSTALLED_APPS = [# ....'user', # 用户信息模块'music', # 收藏模块]作用:
函数格式
模块app命字/url模块名.py 文件件里必须有urlpatterns 列表
使用前需要使用 from django.conf.urls import include 导入此函数
练习:
1.创建四个应用1.创建 index 应用,并注册2.创建 sport 应用,并注册3.创建 news 应用,并注册4.创建 music 应用,并注册2.创建分布式路由系统主路由配置只做分发每个应用中处理具体访问路径和视图1. 127.0.0.1:8000/music/index交给 music 应用中的 index_view() 函数处理2. 127.0.0.1:8000/sport/index交给 sport 应用中的 index_view() 函数处理3. 127.0.0.1:8000/news/index交给 news 应用中的 index_view() 处理处理安装 pymysql包
创建 和 配置数据库
创建数据库
数据库的配置
sqlite 数据库配置
# file: settings.pyDATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3','NAME': os.path.join(BASE_DIR, 'db.sqlite3'),}}mysql 数据库配置
DATABASES = {'default' : {'ENGINE': 'django.db.backends.mysql','NAME': 'mywebdb', # 数据库名称,需要自己定义'USER': 'root','PASSWORD': '123456', # 管理员密码'HOST': '127.0.0.1','PORT': 3306,}}关于数据为的SETTING设置
ENGINE
NAME
USER
PASSWORD
HOST
PORT
添加 mysql 支持
安装pymysql 模块
修改项目中__init__.py 加入如下内容来提供pymysql引擎的支持
import pymysqlpymysql.install_as_MySQLdb()此示例为添加一个 bookstore_book 数据表来存放图书馆中书目信息
添加一个 bookstore 的 app
$ python3 manage.py startapp bookstore添加模型类并注册app
# file : bookstore/models.pyfrom django.db import modelsclass Book(models.Model):title = models.CharField("书名", max_length=50, default='')price = models.DecimalField('定价', max_digits=7, decimal_places=2, default=0.0)注册app
# file : setting.pyINSTALLED_APPS = [...'bookstore',]数据库的迁移
每次修改完模型类再对服务程序运行之前都需要做以上两步迁移操作。
生成迁移脚本文件bookstore/migrations/0001_initial.py并进行迁移
$ python3 manage.py makemigrations$ python3 manage.py migrate编写模型类Models
模型类需继承自django.db.models.Model
Models的语法规范
from django.db import modelsclass 模型类名(models.Model):字段名 = models.字段类型(字段选项)模型类名是数据表名的一部分,建议类名首字母大写
字段名又是当前类的类属性名,此名称将作为数据表的字段名
字段类型用来映射到数据表中的字段的类型
字段选项为这些字段提供附加的参数信息
例如:
from django.db import modelsclass 模型类名(models.Model):字段名 = models.字段类型(字段选项)class Meta:db_table = 'xxxx'BooleanField()
CharField()
DateField()
DateTimeField()
DecimalField()
数据库类型:decimal(x,y)
和钱相关
编程语言中:使用小数表示该列的值
在数据库中:使用小数
参数(必须):
示例:
money=models.DecimalField(max_digits=7,decimal_places=2,default=0.0)FloatField()
EmailField()
IntegerField()
URLField()
ImageField()
数据库类型:varchar(100)
作用:在数据库中为了保存图片的路径
编程语言和数据库中使用字符串
示例:
image=models.ImageField(upload_to="static/images")upload_to:指定图片的上传路径
在后台上传时会自动的将文件保存在指定的目录下
TextField()
参考文档 https://docs.djangoproject.com/en/1.11/ref/models/fields/#field-types
字段选项FIELD_OPTIONS
示例:
# 创建一个属性,表示用户名称,长度30个字符,必须是唯一的,不能为空,添加索引name = models.CharField(max_length=30, unique=True, null=False, db_index=True)文档参见:
当执行 $ python3 manage.py makemigrations 出现如下迁移错误时的处理方法
错误信息
$ python3 manage.py makemigrationsYou are trying to change the nullable field 'title' on book to non-nullable without a default; we can't do that (the database needs something to populate existing rows).Please select a fix:1) Provide a one-off default now (will be set on all existing rows with a null value for this column)2) Ignore for now, and let me handle existing rows with NULL myself (e.g. because you added a RunPython or RunSQL operation to handle NULL values in a previous data migration)3) Quit, and let me add a default in models.pySelect an option:翻译为中文如下:
$ python3 manage.py makemigrations您试图将图书上的可空字段“title”更改为非空字段(没有默认值);我们不能这样做(数据库需要填充现有行)。请选择修复:1)现在提供一次性默认值(将对所有现有行设置此列的空值)2)暂时忽略,让我自己处理空值的现有行(例如,因为您在以前的数据迁移中添加了RunPython或RunSQL操作来处理空值)3)退出,让我在models.py中添加一个默认值选择一个选项:错误原因
处理方法:
数据库的迁移文件混乱的解决办法
每个继承自 models.Model 的模型类,都会有一个 objects 对象被同样继承下来。这个对象叫管理器对象
数据库的增删改查可以通过模型的管理器实现
class MyModel(models.Model):...MyModel.objects.create(...) # objects 是管理器对象Django 使用一种直观的方式把数据库表中的数据表示成Python 对象
创建数据中每一条记录就是创建一个数据对象
MyModel.objects.create(属性1=值1, 属性2=值1,…)
创建 MyModel 实例对象,并调用 save() 进行保存
obj = MyModel(属性=值,属性=值)obj.属性=值obj.save()无返回值,保存成功后,obj会被重新赋值在Django提供了一个交互式的操作项目叫 Django Shell 它能够在交互模式用项目工程的代码执行相应的操作
利用 Django Shell 可以代替编写View的代码来进行直接操作
在Django Shell 下只能进行简单的操作,不能运行远程调式
启动方式:
$ python3 manage.py shell练习:
在 bookstore/models.py 应用中添加两个model类1. Book - 图书1. title - CharField 书名,非空,唯一2. pub - CharField 出版社,字符串,非空3. price - 图书定价,,4. market_price - 图书零售价2. Author - 作者1. name - CharField 姓名,非空2. age - IntegerField, 年龄,非空,缺省值为13. email - EmailField, 邮箱,允许为空然后用 Django Shell 添加如下数据
图书信息
| Python | 20.00 | 25.00 | 清华大学出版社 |
| Python3 | 60.00 | 65.00 | 清华大学出版社 |
| Django | 70.00 | 75.00 | 清华大学出版社 |
| JQuery | 90.00 | 85.00 | 机械工业出版社 |
| Linux | 80.00 | 65.00 | 机械工业出版社 |
| Windows | 50.00 | 35.00 | 机械工业出版社 |
| HTML5 | 90.00 | 105.00 | 清华大学出版社 |
作者信息:
| 王老师 | 28 | wangweichao@tedu.cn |
| 吕老师 | 31 | lvze@tedu.cn |
| 祁老师 | 30 | qitx@tedu.cn |
拓展:
settings.py里 APPEND_SLASH
APPEND_SLASH -> 自动补全 /
案例:
url(r’^page1/$', xx) ,访问浏览器时 地址栏输入 127.0.0.1:8000/page1 ,此时 django接到请求后
返回301【永久重定向】,并在响应头中指定重定向地址为 /page1/ ,从而出现自动补全 / 效果
若要关闭此功能,可将 APPEND_SLASH = False
出现8000端口已占用 解决方案
1,查看是否有django进程启动
ps aux|grep ‘runserver’
2,若grep中出现 相关进程,直接干!
kill -9 pid pid
案例如下:
执行 查!tarena@tedu:~/aid1906/django/day03/mysite3$ ps aux|grep 'runserver'tarena 13984 0.0 0.4 125980 39604 pts/0 S+ 15:39 0:00 python3 manage.py runservertarena 14914 1.2 0.5 202864 41312 pts/0 Sl+ 16:10 0:05 /usr/bin/python3 manage.py runservertarena 15056 0.0 0.0 21532 1156 pts/4 S+ 16:17 0:00 grep --color=auto runserv#执行 干!kill -9 13984 14914插入一条数据
MyModel.objects.create(obj1)
批量创建数据
MyModel.objects.bulk_create([obj1, obj2, obj3])
数据库的查询需要使用管理器对象进行
通过 MyModel.objects 管理器方法调用查询接口
| all() | 查询全部记录,返回QuerySet查询对象 |
| get() | 查询符合条件的单一记录 |
| filter() | 查询符合条件的多条记录 |
| exclude() | 查询符合条件之外的全部记录 |
| … |
方法: all()
用法: MyModel.objects.all()
作用: 查询MyModel实体中所有的数据
返回值: QuerySet容器对象,内部存放 MyModel 实例
示例:
from bookstore import modelsbooks = models.Book.objects.all()for book in books:print("书名", book.title, '出版社:', book.pub)在模型类中定义 def __str__(self): 方法可以将自定义默认的字符串
class Book(models.Model):title = ...def __str__(self):return "书名: %s, 出版社: %s, 定价: %s" % (self.title, self.pub, self.price)方法: values(‘列1’, ‘列2’)
用法: MyModel.objects.values(…)
作用: 查询部分列的数据并返回
返回值: QuerySet
示例:
from bookstore import modelsbooks = models.Book.objects.values("title", "pub")for book in books:print("书名", book["title"], '出版社:', book['pub'])print("book=", book)方法:values_list(‘列1’,‘列2’)
用法:MyModel.objects.values_list(…)
作用:
返回值: QuerySet容器对象,内部存放 元组
示例:
from bookstore import modelsbooks = models.Book.objects.values_list("title", "pub")for book in books:print("book=", book) # ('Python', '清华大学出版社')...方法:order_by
用法:MyModel.objects.order_by(‘-列’,‘列’)
作用:
说明:
默认是按照升序排序,降序排序则需要在列前增加’-'表示
示例:
from bookstore import modelsbooks = models.Book.objects.order_by("-price")for book in books:print("书名:", book.title, '定价:', book.price)根据条件查询多条记录
方法: filter(条件)
语法:
MyModel.objects.filter(属性1=值1, 属性2=值2)返回值:
说明:
示例:
# 查询书中出版社为"清华大学出版社"的图书from bookstore import modelsbooks = models.Book.objects.filter(pub="清华大学出版社")for book in books:print("书名:", book.title)2. 查询Author实体中id为1并且isActive为True的- authors=Author.objects.filter(id=1,isActive=True)字段查询是指如何指定SQL语句中 WHERE 子句的内容。
字段查询需要通过QuerySet的filter(), exclude() and get()的关键字参数指定。
非等值条件的构建,需要使用字段查询
示例:
# 查询作者中年龄大于30Author.objects.filter(age__gt=30)# 对应# SELECT .... WHERE AGE > 30;__exact : 等值匹配
Author.objects.filter(id__exact=1)# 等同于select * from author where id = 1__contains : 包含指定值
Author.objects.filter(name__contains='w')# 等同于 select * from author where name like '%w%'__startswith : 以 XXX 开始
__endswith : 以 XXX 结束
__gt : 大于指定值
Author.objects.filer(age__gt=50)# 等同于 select * from author where age > 50__gte : 大于等于
__lt : 小于
__lte : 小于等于
__in : 查找数据是否在指定范围内
__range: 查找数据是否在指定的区间范围内
# 查找年龄在某一区间内的所有作者Author.objects.filter(age__range=(35,50))# 等同于 SELECT ... WHERE Author BETWEEN 35 and 50;详细内容参见: https://docs.djangoproject.com/en/1.11/ref/models/querysets/#field-lookups
示例
MyModel.objects.filter(id__gt=4)# 等同于 SELECT ... WHERE id > 4;练习:
查询Book表中price大于等于50的信息
Book.objects.filter(price__gte=50)
查询Author表中姓王的人的信息
Author.objects.filter(name__startswith=‘王’)
查询Author表中Email中包含"wc"的人的信息
Author.objects.filter(email__contains=‘wc’)
不等的条件筛选
语法:
MyModel.objects.exclude(条件)
作用:
示例:
语法:
MyModel.objects.get(条件)
作用:
返回值:
说明:
示例:
from bookstore import modelsbook = models.Book.objects.get(id=1)print(book.title)如:
from bookstore import modelsabook = models.Book.objects.get(id=10)abook.market_price = "10.5"abook.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)练习:修改图书得零售价
路由: /bookstore/mod/5
删除单个对象
步骤
示例:
try:auth = Author.objects.get(id=1)auth.delete()except:print(删除失败)删除查询结果集
步骤
示例:
# 删除全部作者中,年龄大于65的全部信息auths = Author.objects.filter(age__gt=65)auths.delete()不带分组聚合
不带分组的聚合查询是指导将全部数据进行集中统计查询
聚合函数:
语法:
返回结果:
示例:
# 得到所有书的平均价格from bookstore import modelsfrom django.db.models import Countresult = models.Book.objects.aggregate(myAvg=Avg('price'))print("平均价格是:", result['myAvg'])print("result=", result) # {"myAvg": 58.2}# 得到数据表里有多少本书from django.db.models import Countresult = models.Book.objects.aggregate(mycnt=Count('title'))print("数据记录总个数是:", result['mycnt'])print("result=", result) # {"mycnt": 10}分组聚合
分组聚合是指通过计算查询结果中每一个对象所关联的对象集合,从而得出总计值(也可以是平均值或总和),即为查询集的每一项生成聚合。
语法:
用法步骤:
通过先用查询结果MyModel.objects.value. 查找查询要分组聚合的列
MyModel.objects.value(‘列1’, ‘列2’)
如:
pub_set = models.Book.objects.values('pub')print(books) # <QuerySet [{'pub': '清华大学出版社'}, {'pub': '清华大学出版社'}, {'pub_hou {'pub': '机械工业出版社'}, {'pub': '清华大学出版社'}]>通过返回结果的 QuerySet.annotate 方法分组聚合得到分组结果
QuerySet.annotate(名=聚合函数(‘列’))
返回 QuerySet 结果集,内部存储结果的字典
如:
pub_count_set = pub_set.annotate(myCount=Count('pub'))print(pub_count_set) # <QuerySet [{'pub': '清华大学出版社', 'myCount': 7}, {'pub': '机械工业出版社', 'myCount': 3}]>示例:
作用:
用法
语法:
from django.db.models import FF('列名')说明:
示例1
示例2
当在获取查询结果集 使用复杂的逻辑或 | 、 逻辑非 ~ 等操作时可以借助于 Q对象进行操作
如: 想找出定价低于20元 或 清华大学出版社的全部书,可以写成
models.Book.objects.filter(Q(price__lt=20)|Q(pub="清华大学出版社"))Q对象在 数据包 django.db.models 中。需要先导入再使用
作用
运算符:
语法
from django.db.models import QQ(条件1)|Q(条件2) # 条件1成立或条件2成立Q(条件1)&Q(条件2) # 条件1和条件2同时成立Q(条件1)&~Q(条件2) # 条件1成立且条件2不成立...示例
from django.db.models import Q# 查找清华大学出版社的书或价格低于50的书models.Book.objects.filter(Q(market_price__lt=50) | Q(pub_house='清华大学出版社'))# 查找不是机械工业出版社的书且价格低于50的书models.Book.objects.filter(Q(market_price__lt=50) & ~Q(pub_house='机械工业出版社'))使用MyModel.objects.raw()进行 数据库查询操作查询
语法:
用法
返回值:
示例
books = models.Book.objects.raw('select * from bookstore_book')for book in books:
print(book)
```
使用django中的游标cursor对数据库进行 增删改操作
在Django中可以使用 如UPDATE,DELETE等SQL语句对数据库进行操作。
在Django中使用上述非查询语句必须使用游标进行操作
使用步骤:
导入cursor所在的包
用创建cursor类的构造函数创建cursor对象,再使用cursor对象,为保证在出现异常时能释放cursor资源,通常使用with语句进行创建操作
如:
from django.db import connectionwith connection.cursor() as cur:cur.execute('执行SQL语句')示例
# 用SQL语句将id 为 10的 书的出版社改为 "XXX出版社"from django.db import connectionwith connection.cursor() as cur: cur.execute('update bookstore_book set pub_house="XXX出版社" where id=10;')with connection.cursor() as cur:# 删除 id为1的一条记录cur.execute('delete from bookstore_book where id=10;')django 提供了比较完善的后台管理数据库的接口,可供开发过程中调用和测试使用
django 会搜集所有已注册的模型类,为这些模型类提拱数据管理界面,供开发者使用
使用步骤:
创建后台管理帐号:
后台管理–创建管理员帐号
guoxiaonao guoxiaonao123
用注册的帐号登陆后台管理界面
若要自己定义的模型类也能在 /admin 后台管理界中显示和管理,需要将自己的类注册到后台管理界面
添加自己定义模型类的后台管理数据表的,需要用admin.site.register(自定义模型类) 方法进行注册
配置步骤如下:
在应用app中的admin.py中导入注册要管理的模型models类, 如:
from . import models调用 admin.site.register 方法进行注册,如:
from django.contrib import adminadmin.site.register(自定义模型类)如: 在 bookstore/admin.py 添加如下代码对Book类进行管理
示例:
# file: bookstore/admin.pyfrom django.contrib import admin# Register your models here.from . import models...admin.site.register(models.Book) # 将Book类注册为可管理页面在admin后台管理数据库中对自定义的数据记录都展示为 XXXX object 类型的记录,不便于阅读和判断
在用户自定义的模型类中可以重写 def __str__(self): 方法解决显示问题,如:
作用:
说明:
模型管理器的使用方法:
在 <应用app>/admin.py 里定义模型管理器类
class XXXX_Manager(admin.ModelAdmin):......注册管理器与模型类关联
from django.contrib import adminfrom . import modelsadmin.site.register(models.YYYY, XXXX_Manager) # 注册models.YYYY 模型类与 管理器类 XXXX_Manager 关联示例:
# file : bookstore/admin.pyfrom django.contrib import adminfrom . import modelsclass BookAdmin(admin.ModelAdmin):list_display = ['id', 'title', 'price', 'market_price']admin.site.register(models.Book, BookAdmin)模型管理器类ModelAdmin中实现的高级管理功能
修改模型类字段的显示名字
模型类各字段的第一个参数为 verbose_name,此字段显示的名字会在后台数据库管理页面显示
通过 verbose_name 字段选项,修改显示名称示例如下:
title = models.CharField(max_length = 30,verbose_name='显示名称')通过Meta内嵌类 定义模型类的属性及展现形式
模型类可以通过定义内部类class Meta 来重新定义当前模型类和数据表的一些属性信息
用法格式如下:
class Book(models.Model):title = CharField(....)class Meta:1. db_table = '数据表名'- 该模型所用的数据表的名称。(设置完成后需要立马更新同步数据库)2. verbose_name = '单数名'- 给模型对象的一个易于理解的名称(单数),用于显示在/admin管理界面中3. verbose_name_plural = '复数名'- 该对象复数形式的名称(复数),用于显示在/admin管理界面中语法
class A(model.Model):...class B(model.Model):属性 = models.OneToOneField(A)用法示例
创建作家和作家妻子类
# file : xxxxxxxx/models.pyfrom django.db import modelsclass Author(models.Model):'''作家模型类'''name = models.CharField('作家', max_length=50)#wife 隐式定义class Wife(models.Model):'''作家妻子模型类'''name = models.CharField("妻子", max_length=50)author = models.OneToOneField(Author) # 增加一对一属性查询
创始一对一的数据记录
from . import modelsauthor1 = models.Author.objects.create(name='王老师')wife1 = models.Wife.objects.create(name='王夫人', author=author1) # 关联王老师#wife1=models.wife.objects.create(name='王夫人', author_id=author1.id)author2 = models.Author.objects.create(name='小泽老师') # 一对一可以没有数据对应的数据一对一数据的相互获取
正向查询
反向查询
作用:
练习:
用法语法
外键类ForeignKey
构造函数:
ForeignKey(to, on_delete, **options)常用参数:
示例
清华大学出版社 有书
北京大学出版社 有书
定义一对多类
# file: one2many/models.pyfrom django.db import modelsclass Publisher(models.Model):'''出版社'''name = models.CharField('名称', max_length=50, unique=True)class Book(models.Model):title = models.CharField('书名', max_length=50)publisher = models.ForeignKey(Publisher, null=True)创建一对多的对象
# file: xxxxx/views.pyfrom . import modelspub1 = models.Publisher.objects.create(name='清华大学出版社')models.Book.objects.create(title='C++', publisher=pub1)models.Book.objects.create(title='Java', publisher=pub1)models.Book.objects.create(title='Python', publisher=pub1)pub2 = models.Publisher.objects.create(name='北京大学出版社')models.Book.objects.create(title='西游记', publisher=pub2)models.Book.objects.create(title='水浒', publisher=pub2)查询:
数据查询
通过 Book 查询 Publisher
通过 publisher 属性查询即可练习:查询 西游记 对应的出版社信息,打印在终端上通过 Publisher 查询 对应的所有的 Books
Django会在Publisher中增加一个属性来表示对对应的Book们的查询引用属性:book_set(MyModel.objects)语法
示例
数据查询
通过 Book 查询对应的所有的 Authors
book.authors.all() -> 获取 book 对应的所有的author的信息book.authors.filter(age__gt=80) -> 获取book对应的作者中年龄大于80岁的作者的信息通过 Author 查询对应的所有的Books
示例:
cookies是保存在客户端浏览器上的存储空间,通常用来记录浏览器端自己的信息和当前连接的确认信息
cookies 在浏览器上是以键-值对的形式进行存储的,键和值都是以ASCII字符串的形存储(不能是中文字符串)
cookies 的内部的数据会在每次访问此网址时都会携带到服务器端,如果cookies过大会降低响应速度
在Django 服务器端来设置 设置浏览器的COOKIE 必须通过 HttpResponse 对象来完成
HttpResponse 关于COOKIE的方法
添加、修改COOKIE
删除COOKIE
Django中的cookies
使用 响应对象HttpResponse 等 将cookie保存进客户端
方法1
from django.http import HttpResponseresp = HttpResponse()resp.set_cookie('cookies名', cookies值, 超期时间)方法二, 使用render对象
from django.shortcuts import renderresp = render(request,'xxx.html',locals())resp.set_cookie('cookies名', cookies值, 超期时间)获取cookie
通过 request.COOKIES 绑定的字典(dict) 获取客户端的 COOKIES数据
value = request.COOKIES.get('cookies名', '没有值!')print("cookies名 = ", value)注:
cookies 示例
以下示例均在视图函数中调用
添加cookie
# 为浏览器添加键为 my_var1,值为123,过期时间为1个小时的cookieresponds = HttpResponse("已添加 my_var1,值为123")responds.set_cookie('my_var1', 123, 3600)return responds修改cookie
# 为浏览器添加键为 my_var1,修改值为456,过期时间为2个小时的cookieresponds = HttpResponse("已修改 my_var1,值为456")responds.set_cookie('my_var1', 456, 3600*2)return responds删除cookie
# 删除浏览器键为 my_var1的cookieresponds = HttpResponse("已删除 my_var1")responds.delete_cookie('my_var1')return responds获取cookie
# 获取浏览器中 my_var变量对应的值value = request.COOKIES.get('my_var1', '没有值!')print("cookie my_var1 = ", value)return HttpResponse("my_var1:" + value)综合练习:
实现用户注册功能,界面如下:
要求 :
模型类
用户模型类
class User(models.Model):username = models.CharField("用户名", max_length=30, unique=True)password = models.CharField("密码", max_length=30)def __str__(self):return "用户" + self.username登陆设计规范(在user应用中写代码)
| /user/reg | def reg_view(request): | templates/user/register.html | 用户注册 |
什么是session
session又名会话控制,是在服务器上开辟一段空间用于保留浏览器和服务器交互时的重要数据
session的起源
实现方式
Django启用Session
在 settings.py 文件中
向 INSTALLED_APPS 列表中添加:
INSTALLED_APPS = [# 启用 sessions 应用'django.contrib.sessions',]向 MIDDLEWARE_CLASSES 列表中添加:
MIDDLEWARE = [# 启用 Session 中间件'django.contrib.sessions.middleware.SessionMiddleware',]session的基本操作:
注: 当使用session时需要迁移数据库,否则会出现错误
模型类
用户模型类
class User(models.Model):username = models.CharField("用户名", max_length=30, unique=True)password = models.CharField("密码", max_length=30)create_time = models.DateTimeField('创建时间', auto_now_add=True)def __str__(self):return "用户" + self.username笔记模型类
登陆设计规范(在user应用中写代码)
| /user/login | def login_view(request): | templates/user/login.html | 用户登陆 |
| /user/reg | def reg_view(request): | templates/user/register.html | 用户注册 |
| /user/logout | def logout_view(request): | 无 | 退出用户登陆 |
登陆界面
注册界面
主页设计规范(在index应用中写代码)
| / | def index_view(request): | templates/index/index.html | 主页 |
登陆前
登陆后
云笔记设计规范
| /note/ | def list_view(request): | templates/note/list_note.html | 显示笔记列表功能 |
| /note/add | def add_view(request): | templates/note/add_note.html | 添加云笔记 |
| /note/mod/(\d+) | def mod_view(request, id): | templates/note/mod_note.html | 修改之前云笔记 |
| /note/del/(\d+) | def del_view(request, id): | 无(返回列表页) | 删除云笔记 |
| /note/(\d+) | def show_view(request, id): | templates/note/note.html | 查看单个云笔记 |
登陆界面
注册界面
添加新笔记界面
显示笔记列表
修改云笔记
主页
登陆前
登陆后
缓存是一类可以更快的读取数据的介质统称,也指其它可以加快数据读取的存储方式。一般用来存储临时数据,常用介质的是读取速度很快的内存
视图渲染有一定成本,对于低频变动的页面可以考虑使用缓存技术,减少实际渲染次数
案例分析
from django.shortcuts import renderdef index(request):# 时间复杂度极高的渲染book_list = Book.objects.filter() #-> 此处假设耗时2sreturn render(request, 'index.html', locals())优化思想
given a URL, try finding that page in the cacheif the page is in the cache:return the cached pageelse:generate the pagesave the generated page in the cache (for next time)return the generated page1,博客列表页
2,电商商品详情页
3,缓存导航及页脚
https://docs.djangoproject.com/en/1.11/topics/cache/
Django中提供多种缓存方式,如需使用需要在settings.py中进行配置
1,数据库缓存
Django可以将其缓存的数据存储在您的数据库中
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.db.DatabaseCache','LOCATION': 'my_cache_table','OPTIONS':{'MAX_ENTRIES': 300, #当前最大缓存数'CULL_FREQUENCY': 3 #删除频率 1/cull_frequency}}}创建缓存表
python3 manage.py createcachetable2,文件系统缓存
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache','LOCATION': '/var/tmp/django_cache',#这个是文件夹的路径#'LOCATION': 'c:\test\cache',#windows下示例}}3, 本地内存缓存
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache','LOCATION': 'unique-snowflake'}}在视图View中使用cache
from django.views.decorators.cache import cache_page@cache_page(30) -> 单位sdef my_view(request):...在路由中使用
from django.views.decorators.cache import cache_pageurlpatterns = [path('foo/', cache_page(60)(my_view)),]在模板中使用
{% load cache %} {% cache 50 sidebar request.user.username %} .. sidebar for logged in user ..{% endcache %}cache_key = sidebar + username
guoxiaonao访问 时 cache_key = sidebar + guoxiaonao
浏览器缓存分类:
不会向服务器发送请求,直接从缓存中读取资源
1,Expires
缓存过期时间,用来指定资源到期的时间,是服务器端的具体的时间点
Expires=max-age + 请求时间 UTC绝对时间
2019 10 27 xxx
Expires 是 HTTP/1 的产物,受限于本地时间,如果修改了本地时间,可能会造成缓存失效
2, Cache-Control
在HTTP/1.1中,Cache-Control主要用于控制网页缓存。比如当Cache-Control:max-age=120 代表请求创建时间后的120秒,缓存失效
横向对比 Expires VS Cache-Control
**协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程
1,Last-Modified和If-Modified-Since
第一次访问时,服务器会返回
Last-Modified: Fri, 22 Jul 2016 01:47:00 GMT
浏览器下次请求时 携带If-Modified-Since这个header , 该值为 Last-Modified
服务器接收请求后,对比结果,若资源未发生改变,则返回304, 否则返回200并将新资源返回给浏览器
缺点:只能精确到秒,容易发生单秒内多次修改,检测不到
2,ETag和If-None-Match
Etag是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成),只要资源有变化,Etag就会重新生成
流程同上
横向对比 Last-Modified VS ETag
中间件是 Django 请求/响应处理的钩子框架。它是一个轻量级的、低级的“插件”系统,用于全局改变 Django 的输入或输出。
每个中间件组件负责做一些特定的功能。例如,Django 包含一个中间件组件 AuthenticationMiddleware,它使用会话将用户与请求关联起来。
他的文档解释了中间件是如何工作的,如何激活中间件,以及如何编写自己的中间件。Django 具有一些内置的中间件,你可以直接使用。它们被记录在 built-in middleware reference 中。
中间件类:
编写中间件类:
中间件的执行过程
练习
用中间件实现强制某个IP地址只能向/test 发送 5 次GET请求
提示:
答案:
from django.http import HttpResponse, Http404from django.utils.deprecation import MiddlewareMixinimport reclass VisitLimit(MiddlewareMixin):'''此中间件限制一个IP地址对应的访问/user/login 的次数不能改过10次,超过后禁止使用'''visit_times = {} # 此字典用于记录客户端IP地址有访问次数def process_request(self, request):ip_address = request.META['REMOTE_ADDR'] # 得到IP地址if not re.match('^/test', request.path_info):returntimes = self.visit_times.get(ip_address, 0)print("IP:", ip_address, '已经访问过', times, '次!:', request.path_info)self.visit_times[ip_address] = times + 1if times < 5:returnreturn HttpResponse('你已经访问过' + str(times) + '次,您被禁止了')跨站请求伪造攻击
说明:
CSRF中间件和模板标签提供对跨站请求伪造简单易用的防护。
作用:
解决方案:
取消 csrf 验证(不推荐)
通过验证 csrf_token 验证
需要在表单中增加一个标签 {% csrf_token %}对象的构造方法
Paginator属性
Paginator方法
Paginator异常exception
创建对象
Paginator对象的page()方法返回Page对象,不需要手动构造
Page对象属性
Page对象方法
说明:
参考文档https://docs.djangoproject.com/en/1.11/topics/pagination/
分页示例:
文件上传必须为POST提交方式
表单<form>中文件上传时必须有带有enctype="multipart/form-data" 时才会包含文件内容数据。
表单中用<input type="file" name="xxx">标签上传文件
上传文件的表单书写方式
<!-- file: index/templates/index/upload.html --><html><head><meta charset="utf-8"><title>文件上传</title></head><body><h3>上传文件</h3><form method="post" action="/upload" enctype="multipart/form-data"><input type="file" name="myfile"/><br><input type="submit" value="上传"></form></body></html>在setting.py 中设置一个变量MEDIA_ROOT 用来记录上传文件的位置
# file : settings.py...MEDIA_ROOT = os.path.join(BASE_DIR, 'static/files')在当前项目文件夹下创建 static/files 文件夹
$ mkdir -p static/files添加路由及对应的处理函数
# file urls.pyurlpatterns = [url(r'^admin/', admin.site.urls),url(r'^upload', views.upload_view)]上传文件的视图处理函数
# file views.pyfrom django.http import HttpResponse, Http404from django.conf import settingsimport osdef upload_view(request):if request.method == 'GET':return render(request, 'index/upload.html')elif request.method == "POST":a_file = request.FILES['myfile']print("上传文件名是:", a_file.name)filename =os.path.join(settings.MEDIA_ROOT, a_file.name)with open(filename, 'wb') as f:data = a_file.file.read()f.write(data)return HttpResponse("接收文件:" + a_file.name + "成功")raise Http404访问地址: http://127.0.0.1:8000/static/upload.html
后端缓存:
1, 将视图函数最终结果 转存到其他介质里
【mysql表里,文件里, 内存里】
2,解决了 views重复计算问题 【有效降低视图层时间复杂度】
3,http 1.1 cache头 触发了 浏览器强缓存
浏览器缓存:
1,带有强缓存的响应头 的响应数据,存储自己的硬盘中或内存里
2,当强缓存有数据时,可以完全不给服务器发送请求,直接读取缓存内容 【减少 浏览器与服务器之间的请求次数】
Django带有一个用户认证系统。 它处理用户账号、组、权限以及基于cookie的用户会话。
作用:
文档参见
https://docs.djangoproject.com/en/1.11/topics/auth/
User模型类
位置: from django.contrib.auth.models import User
默认user的基本属性有:
| username | 用户名 | 是 |
| password | 密码 | 是 |
| 邮箱 | 可选 | |
| first_name | 名 | |
| last_name | 姓 | |
| is_superuser | 是否是管理员帐号(/admin) | |
| is_staff | 是否可以访问admin管理界面 | |
| is_active | 是否是活跃用户,默认True。一般不删除用户,而是将用户的is_active设为False。 | |
| last_login | 上一次的登录时间 | |
| date_joined | 用户创建的时间 |
数据库表现形式
创建用户
创建普通用户create_user
from django.contrib.auth import modelsuser = models.User.objects.create_user(username='用户名', password='密码', email='邮箱',...)...user.save()创建超级用户create_superuser
from django.contrib.auth import modelsuser = models.User.objects.create_superuser(username='用户名', password='密码', email='邮箱',...)...user.save()删除用户
from django.contrib.auth import modelstry:user = models.User.objects.get(username='用户名')user.is_active = False # 记当前用户无效user.save()print("删除普通用户成功!")except:print("删除普通用户失败")return HttpResponseRedirect('/user/info')修改密码set_password
from django.contrib.auth import modelstry:user = models.User.objects.get(username='xiaonao')user.set_password('654321')user.save()return HttpResponse("修改密码成功!")except:return HttpResponse("修改密码失败!")检查密码是否正确check_password
from django.contrib.auth import modelstry:user = models.User.objects.get(username='xiaonao')if user.check_password('654321'): # 成功返回True,失败返回Falsereturn HttpResponse("密码正确")else:return HttpResponse("密码错误")except:return HttpResponse("没有此用户!")Django可直接在视图函数中生成csv文件 并响应给浏览器
import csvfrom django.http import HttpResponsefrom .models import Bookdef make_csv_view(request):response = HttpResponse(content_type='text/csv')response['Content-Disposition'] = 'attachment; filename="mybook.csv"'all_book = Book.objects.all()writer = csv.writer(response)writer.writerow(['id', 'title'])for b in all_book: writer.writerow([b.id, b.title])return response视图函数中
from django.core import mailmail.send_mail(subject, #题目message, # 消息内容from_email, # 发送者[当前配置邮箱]recipient_list=['xxx@qq.com',], # 接收者邮件列表auth_password='xxxxxxx' # 在QQ邮箱->设置->帐户->“POP3/IMAP......服务” 里得到的在第三方登录QQ邮箱授权码)安装同版本的数据库
django 项目迁移
安装python
安装相同版本的包
将当前项目源代码复制到远程主机上(scp 命令)
$ sudo scp -a 当前项目源代码 远程主机地址和文件夹
使用 python manage.py runserver 通常只在开发和测试环境中使用。
当开发结束后,完善的项目代码需要在一个高效稳定的环境中运行,这时可以使用uWSGI
uWSGI是WSGI的一种,它可以让Django、Flask等开发的web站点运行其中.
安装uWSGI
在线安装 uwsgi
$ sudo pip3 install uwsgi离线安装
在线下载安装包:
$ pip3 download uwsgi离线安装
$ tar -xzvf uwsgi-2.0.18.tar.gz$ cd uwsgi-2.0.18$ sudo python3 setup.py install配置uWSGI
添加配置文件 项目文件夹/uwsgi.ini
修改settings.py将 DEBUG=True 改为DEBUG=False
修改settings.py 将 ALLOWED_HOSTS = [] 改为 ALLOWED_HOSTS = [‘*’]
uWSGI的运行管理
启动 uwsgi
$ cd 项目文件夹$ sudo uwsgi --ini 项目文件夹/uwsgi.ini停止 uwsgi
$ cd 项目文件夹$ sudo uwsgi --stop uwsgi.pid说明:
测试:
Nginx是轻量级的高性能Web服务器,提供了诸如HTTP代理和反向代理、负载均衡、缓存等一系列重要特性,在实践之中使用广泛。
C语言编写,执行效率高
nginx 作用
原理:
客户端请求nginx,再由nginx 请求 uwsgi, 运行django下的python代码
ubuntu 下 nginx 安装
$ sudo apt install nginx
nginx 配置
nginx服务控制
$ sudo /etc/init.d/nginx start|stop|restart|status# 或$ sudo service nginx start|stop|restart|status通过 start,stop,restart,status 可能实现nginx服务的启动、停止、重启、查扑克状态等操作
修改uWSGI配置
测试:
解决静态路径问题
# file : /etc/nginx/sites-available/default# 新添加location /static 路由配置,重定向到指定的绝对路径server {...location /static {# root static文件夹所在的绝对路径,如:root /home/tarena/my_django_project; # 重定向/static请求的路径,这里改为你项目的文件夹}...}修改配置文件后需要重新启动 nginx 服务
在模板文件夹内添加 404.html 模版,当视图触发Http404 异常时将会被显示
404.html 仅在发布版中(即setting.py 中的 DEBUG=False时) 才起作用
当向应处理函数触发Http404异常时就会跳转到404界面
from django.http import Http404def xxx_view(request):raise Http404 # 直接返回404