前言 Django学习笔记
安装Django模块
Django的命令 初始化项目
<project_name>
:项目名称
1 2 django-admin startproject <project_name> cd <project_name>
目录结构 1 2 3 4 5 6 7 + <project_name> 外层项目目录 + <project_name> 内层项目目录 - __init__.py 一个模块 - settings.py 配置文件 - urls.py 路由文件 - wsgi.py 部署时的网关 - manage.py Python可执行文件,内置了一些Django命令
启动项目(开发阶段)
1 python manage.py runserver
指定IP和端口
1 python manage.py runserver 127.0.0.1:8000
允许局域网访问
IP为0.0.0.0
表示局域网中的任何IP都可以访问
1 python manage.py runserver 0.0.0.0:8000
踩坑
报错:django.core.exceptions.DisallowedHost: Invalid HTTP_HOST header: ''. You may need to add '' to ALLOWED_HOSTS.
原因:没有配置允许请求的主机
解决问题:配置允许请求的主机
<project_name>/<project_name>/setting.py
创建子应用
<app_name>
:子应用名称
1 python manage.py startapp <app_name>
目录结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 + <project_name> + <project_name> - __init__.py - settings.py - urls.py - wsgi.py - manage.py - db.sqlite3 + <app_name> - __init__.py - admin.py 后台管理站点的配置 - apps.py 当前子应用的相关信息 + migrations 数据库迁移历史文件 - __init__.py - models.py 保存数据库模型类 - tests.py 单元测试 - views.py Web应用视图
查看帮助
进入调试模式
数据库创建更改文件 1 python manage.py makemigrations
同步到数据库进行更新 1 python manage.py migrate
清空数据库
在Shell中开发
Django中的模块
模型(Model):数据层,处理与数据相关的所有事物
视图(View):视图层,用来处理用户发出的请求
模版(Template):模版层,通过视图函数渲染HTML模版,得到动态的前端页面
路由(Url):网站的入口,关联到对应的视图函数,将访问网址映射为函数
表单(Forms):表单,用在浏览器输入数据的提交,并对这些数据进行验证
后台(Admin):Django自带一个管理后台,对提交的数据进行管理
配置(Settings):Django的配置文件
Django的全局配置
<project_name>/<project_name>/settings.py
BASE_DIR
:返回项目目录所在的绝对路径SECRET_KEY
:数据加密的密钥,防止被跨域攻击DEBUG
:网站是否处于开发模式,默认为True
,网站上线前应当改成False
ALLOWED_HOSTS
:网站访问白名单,如果允许任何网站,可以设置为['*']
INSTALLED_APPS
:应用注册MIDDLEWARE
:中间件ROOT_URLCONF
:网站入口跟路由配置TEMPLATES
:配置HTML静态文件WSGI_APPLICATION
:配置开发服务器DATABASES
:配置数据库AUTH_PASSWORD_VALIDATORS
:用户密码加密LANGUAGE_CODE
:网站默认语言
en-us
:缺省值,英文zh-hans
:简体中文
TIME_ZONE
:默认时间
UTC
:缺省值,国际标准时间Asia/Shanghai
:上海时间
USE_I18N
:是否开启多语言支持USE_TZ
:改成FalseSTATIC_URL
:静态资源路径
子应用 创建子应用 1 python manage.py startapp <app_name>
修改全局配置
在配置文件的INSTALLED_APPS
列表末尾追加子应用名作为列表的元素,注册子应用到全局配置
<project_name>/<project_name>/settings.py 1 2 3 4 5 6 7 8 9 INSTALLED_APPS = [ 'django.contrib.admin' , 'django.contrib.auth' , 'django.contrib.contenttypes' , 'django.contrib.sessions' , 'django.contrib.messages' , 'django.contrib.staticfiles' , '<app_name>' , ]
在子应用中创建一个页面 通过函数渲染数据 在视图响应一些数据
<project_name>/<app_name>/views.py 1 2 3 4 5 from django.shortcuts import renderfrom django.http import HttpResponsedef index (request ): return HttpResponse("hello word !" )
在子应用中创建一个路由
index
:视图层定义的函数名
<project_name>/<app_name>/urls.py 1 2 3 4 5 6 from django.urls import pathfrom .views import indexurlpatterns = [ path('' , index), ]
将子路由绑定到跟路由
引入include
模块
通过include()
引入子路由
<project_name>/<project_name>/urls.py 1 2 3 4 5 6 7 from django.contrib import adminfrom django.urls import path, includeurlpatterns = [ path('admin/' , admin.site.urls), path('' , include('<app_name>.urls' )), ]
通过Message类渲染数据 在视图响应一些数据
<project_name>/<app_name>/views.py 1 2 3 4 5 6 from django.views.generic import Viewfrom django.http import HttpResponseclass Message (View ): def get (self, request ): return HttpResponse("hello word !" )
在子应用中创建一个路由
index
:视图层定义的函数名
<project_name>/<app_name>/urls.py 1 2 3 4 5 6 from django.urls import pathfrom .views import Messageurlpatterns = [ path('' , Message.as_view()), ]
将子路由绑定到跟路由
引入include
模块
通过include()
引入子路由
<project_name>/<project_name>/urls.py 1 2 3 4 5 6 7 from django.contrib import adminfrom django.urls import path, includeurlpatterns = [ path('admin/' , admin.site.urls), path('' , include('<app_name>.urls' )), ]
处理请求参数 处理GET请求请求参数 普通传递参数方式 http://127.0.0.1:8000/index?key=value
<project_name>/<app_name>/urls.py 1 2 3 4 5 6 from django.urls import pathfrom .views import indexurlpatterns = [ path('index' , index), ]
key
:参数键value
:得到的参数值default
:如果没有指定键时的默认值
<project_name>/<app_name>/views.py 1 2 3 4 5 6 7 from django.shortcuts import renderfrom django.http import HttpResponsedef index (request ): value = request.GET.get("key" , "default" ) print (value) return HttpResponse("hello word !" )
RUSTful风格的传递参数方式 http://127.0.0.1:8000/index/value
在子路由中定义接收请求参数的占位符<str:param>
,其中:
前部分表示数据类型,:
后部分表示形参名
支持的类型
str
:字符串int
:整型slug
:任何类型都可获取uuid
:形似xxx-xx-xx
<project_name>/<app_name>/urls.py 1 2 3 4 5 6 from django.urls import pathfrom .views import indexurlpatterns = [ path('index/<str:param>' , index), ]
<project_name>/<app_name>/views.py 1 2 3 4 5 6 from django.shortcuts import renderfrom django.http import HttpResponsedef index (request, param ): print (param) return HttpResponse("hello word !" )
处理POST请求请求参数 关闭CSRFToken验证
将django.middleware.csrf.CsrfViewMiddleware
中间件注释
<project_name>/<project_name>/setting.py 1 2 3 4 5 6 7 8 9 MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware' , 'django.contrib.sessions.middleware.SessionMiddleware' , 'django.middleware.common.CommonMiddleware' , 'django.contrib.auth.middleware.AuthenticationMiddleware' , 'django.contrib.messages.middleware.MessageMiddleware' , 'django.middleware.clickjacking.XFrameOptionsMiddleware' , ]
1 2 3 4 5 def index (request ): if request.method == "POST" : value = request.POST.getlist('key' ) ...
JSON传递参数方式 1 2 3 4 5 6 def index (request ): if request.method == "POST" : json_param = json.loads(request.body.decode()) value = json_param.get("key" , "default" ) ...
请求对象
request对象
request.GET
:处理GET请求提交的数据request.POST
:处理POST请求提交的数据request.path
:获取请求路径request.method
:获取请求方式request.COOKIES
:获取请求时携带的Cookie信息request.user
:请求的用户对象,用来判断用户是否登录,并用来获取用户信息request.session
:获取Session信息request.META
:一个标准的Python字典,包含所有的HTTP首部
响应对象
HttpResponse响应对象:直接返回字符串 render:将数据在模版中渲染并显示 JsonResponse:返回JSON格式的字符串
渲染模版
创建templates目录
在项目根目录创建templates
目录,用于存放模版
在templates目录下创建一个index.html
文件
<project_name>/templates/index.html 1 2 3 4 5 6 7 8 9 10 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > </head > <body > </body > </html >
修改全局配置
在配置文件的TEMPLATES[0].DIRS
列表添加配置
<project_name>/<project_name>/settings.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 TEMPLATES = [ { 'BACKEND' : 'django.template.backends.django.DjangoTemplates' , 'DIRS' : [os.path.join(BASE_DIR, 'templates' )], 'APP_DIRS' : True , 'OPTIONS' : { 'context_processors' : [ 'django.template.context_processors.debug' , 'django.template.context_processors.request' , 'django.contrib.auth.context_processors.auth' , 'django.contrib.messages.context_processors.messages' , ], }, }, ]
在子应用视图层渲染HTML文件 不传递数据给页面 <project_name>/<app_name>/views.py 1 2 3 4 5 6 from django.shortcuts import renderfrom django.views.generic import Viewclass Index (View ): def get (self, request ): return render(request, 'index.html' )
传递数据给页面
{'key': 'value'}
:通过字典的形式传递给页面
<project_name>/<app_name>/views.py 1 2 3 4 5 6 from django.shortcuts import renderfrom django.views.generic import Viewclass Index (View ): def get (self, request ): return render(request, 'index.html' , {'key' : 'value' })
页面中使用传递的数据
<project_name>/templates/index.html 1 2 3 4 5 6 7 8 9 10 11 12 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > </head > <body > <h1 > Hello {{ key }}</h1 > </body > </html >
在子应用中创建一个路由
index
:视图层定义的函数名
<project_name>/<app_name>/urls.py 1 2 3 4 5 6 from django.urls import pathfrom .views import Indexurlpatterns = [ path('' , Index.as_view()), ]
将子路由绑定到跟路由
引入include
模块
通过include()
引入子路由
<project_name>/<project_name>/urls.py 1 2 3 4 5 6 7 from django.contrib import adminfrom django.urls import path, includeurlpatterns = [ path('admin/' , admin.site.urls), path('' , include('<app_name>.urls' )), ]
静态文件 创建static目录
修改全局配置
在全局配置文件末尾添加STATICFILES_DIRS
配置
1 2 3 STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static' ) ]
使用静态文件 传送门
模版中的内置标签 获取传递过来的数据
key
:根据字典的键,获取对应的值
分支语句 1 2 3 4 5 {% if 条件 %} {% elif 条件 %} {% endif %}
循环语句 遍历数据
如果在字典中传递了一个列表,可以通过for...in
进行循环遍历
1 2 3 4 5 {% for item in 可遍历数据 %} {{ item }} {% endfor %}
遍历索引值 从0开始 1 2 3 4 5 {% for item in 可遍历数据 %} {{ forloop.counter0 }} {% endfor %}
从1开始 1 2 3 4 5 {% for item in 可遍历数据 %} {{ forloop.counter }} {% endfor %}
从结尾开始直到0 1 2 3 4 5 {% for item in 可遍历数据 %} {{ forloop.revcounter0 }} {% endfor %}
从结尾开始直到1 1 2 3 4 5 {% for item in 可遍历数据 %} {{ forloop.revcounter }} {% endfor %}
判断数据 是否是第一个值
1 2 3 4 5 6 7 {% for item in 可遍历数据 %} {% if forloop.first %} {% endif %} {% endfor %}
是否是最后一个值
1 2 3 4 5 6 7 {% for item in 可遍历数据 %} {% if forloop.last %} {% endif %} {% endfor %}
是否是空列表
通常将{% empty %}
语句放在循环语句末尾,如果遍历的是一个空列表,那么在{% empty %}
后的语句将会被执行
1 2 3 4 5 6 7 {% for item in 可遍历数据 %} {% empty %} 当前列表为空 {% endfor %}
加载静态文件
在模版头部加载Django的标签库staticfiles
img/picture.jpg
:静态资源在static
目录下的相对路径
1 <img src ="{% static 'img/picture.jpg' %}" >
继承和重写 子模版继承父模版
<father>
:父模版
子模版重写父模版 1 2 {% block data %} {% endblock %}
跨域密钥
模版中的过滤器 过滤器的基本语法
将传递到模版的数据通过计算后再展现在页面上
竖线左右不能包含空格
内置过滤器 加
日期格式化 1 {{ 变量名|date:"Y-m-d H:i:s" }}
去除字符串中的所有指定字符
首字母大写
判断值是否存在
如果存在或为True,则显示原本值
如果不存在或为False,则显示默认值
判断值是否为None
如果不为None,则显示原本值
如果为None,则显示默认值
1 {{ 变量名|default_if_none:"默认值" }}
列表排序
如果传递的值是一个包含多个字典的列表,可以将列表根据字典的指定属性的值排序
正序
[{key1: value1, key2: value2}, {key1: value1, key2: value2}]
1 {{ 变量名|dictsort:"key1" }}
倒序
1 {{ 变量名|dictsortreversed:"key1" }}
获取列表中的第一个值
获取列表中的最后一个值
保留2位小数
将列表用指定字符拼接
获取值的长度
判断值的长度
如果值的长度等于指定数字,则为True
如果值的长度不等于指定数字,则为False
判断是否可以被整除
将获取的值与指定数字整除
如果能整除则为True
如果不能整除则为False
1 {{ 变量名|divisibleby:数字 }}
将值作为前端代码解析
随机返回列表中的一个元素
字符串切片
分隔单词
将字符串中所有的符号删除,将单词与单词之间用-
分隔
单词全部大写
将链接自动变成超链接
如果一个字符串中包含URL,则URL自动转换成可点击的超链接
单词计数
计算时间差
传递一个未来时间作为值,获取未来时间与当前时间的时间差
自定义过滤器 创建自定义过滤器
在当前子应用下创建一个Python的包,包名为templatetags
,在包内创建Python文件作为自定义的过滤器,文件名自定义
1 2 3 4 5 + <project_name> + <app_name> + templatetags - __init__.py - 自定义过滤器名.py
<project_name>/<app_name>/templatetags/自定义过滤器名.py
value
:传递到模版的值args
:参数
1 2 3 4 5 6 7 8 from django import templateregister = template.Library() @register.filter def test_filter (value, args ): return
使用自定义过滤器
第三方模版 JinJa2 下载依赖
创建配置文件
在当前子应用下创建一个Python文件作为jinja2的配置,文件名为base_jinja2.py
<project_name>/<app_name>/base_jinja2.py 1 2 3 4 5 6 7 8 9 10 11 from jinja2 import Environmentfrom django.contrib.staticfiles.storage import staticfiles_storagefrom django.urls import reversedef environment (**options ): env = Environment(**options) env.globals .update({ 'static' : staticfiles_storage.url, 'url' : reverse }) return env
修改全局配置
全局配置中默认的过滤器BACKEND
是内置过滤器,需要添加JinJa2的过滤器
在TEMPLATES
数组中添加一个过滤器配置
将BACKEND
设置为django.template.backends.jinja2.Jinja2
将OPTIONS
添加environment
配置
<project_name>/<project_name>/settings.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 TEMPLATES = [ { 'BACKEND' : 'django.template.backends.jinja2.Jinja2' , 'DIRS' : [os.path.join(BASE_DIR, 'templates' )], 'APP_DIRS' : True , 'OPTIONS' : { 'context_processors' : [ 'django.template.context_processors.debug' , 'django.template.context_processors.request' , 'django.contrib.auth.context_processors.auth' , 'django.contrib.messages.context_processors.messages' , ], 'environment' : 'index.base_jinja2.environment' , }, }, { 'BACKEND' : 'django.template.backends.django.DjangoTemplates' , 'DIRS' : [os.path.join(BASE_DIR, 'templates' )], 'APP_DIRS' : True , 'OPTIONS' : { 'context_processors' : [ 'django.template.context_processors.debug' , 'django.template.context_processors.request' , 'django.contrib.auth.context_processors.auth' , 'django.contrib.messages.context_processors.messages' , ], }, }, ]
在子应用视图层渲染HTML文件 不传递数据给页面 <project_name>/<app_name>/views.py 1 2 3 4 5 6 from django.shortcuts import renderfrom django.views.generic import Viewclass Index (View ): def get (self, request ): return render(request, 'index.html' )
传递数据给页面
{'key': 'value'}
:通过字典的形式传递给页面
<project_name>/<app_name>/views.py 1 2 3 4 5 6 from django.shortcuts import renderfrom django.views.generic import Viewclass Index (View ): def get (self, request ): return render(request, 'index.html' , {'key' : 'value' })
页面中使用传递的数据
<project_name>/templates/index.html 1 2 3 4 5 6 7 8 9 10 11 12 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > </head > <body > <h1 > Hello {{ key }}</h1 > </body > </html >
在子应用中创建一个路由
index
:视图层定义的函数名
<project_name>/<app_name>/urls.py 1 2 3 4 5 6 from django.urls import pathfrom .views import Indexurlpatterns = [ path('' , Index.as_view()), ]
将子路由绑定到跟路由
引入include
模块
通过include()
引入子路由
<project_name>/<project_name>/urls.py 1 2 3 4 5 6 7 from django.contrib import adminfrom django.urls import path, includeurlpatterns = [ path('admin/' , admin.site.urls), path('' , include('<app_name>.urls' )), ]
过滤器 过滤器的基本语法
JinJa2内置过滤器 首字母大写
自定义过滤器 创建自定义过滤器
直接在子应用根目录下创建一个Python文件作为自定义过滤器,文件名自定义
<project_name>/<app_name>/自定义过滤器名.py 1 2 3 def 自定义过滤器函数名 (value, args ): return
在jinja2配置文件中添加配置 <project_name>/<app_name>/base_jinja2.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 from jinja2 import Environmentfrom django.contrib.staticfiles.storage import staticfiles_storagefrom django.urls import reversefrom .自定义过滤器名 import 自定义过滤器函数名def environment (**options ): env = Environment(**options) env.globals .update({ 'static' : staticfiles_storage.url, 'url' : reverse }) env.filters['自定义过滤器名' ] = 自定义过滤器函数名 return env
使用自定义过滤器
静态文件 创建static目录
使用静态文件
当使用JinJa2作为第三方模版后,在模版内可以直接使用<project_name>/static
目录下的静态文件
1 <img src ="img/picture.jpg" >
mako 下载依赖
创建配置文件
在当前子应用下创建一个Python文件作为mako的配置,文件名为base_render.py
<project_name>/<app_name>/base_render.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 from mako.lookup import TemplateLookupfrom django.conf import settingsfrom django.http import HttpResponsefrom django.template import RequestContextfrom django.template.context import Contextdef render_to_response (request, template, data=None ): context_instance = RequestContext(request) path = settings.TEMPLATES[0 ]['DIRS' ][0 ] lookup = TemplateLookup( directories=[path], input_encoding='utf-8' , output_encoding='utf-8' , ) mako_template = lookup.get_template(template) if not data: data = {} if context_instance: context_instance.update(data) else : context_instance = Context(data) result = {} for item in context_instance: result.update(item) result['csrf_token' ] = '<input type="hidden" name="csrfmiddlewaretoken" value="{}" />' .format (request.META.get('CSRF_COOKIE' , '' )) return HttpResponse(mako_template.render(**result))
在子应用视图层渲染HTML文件 不传递数据给页面 <project_name>/<app_name>/views.py 1 2 3 4 5 6 from .base_render import render_to_responsefrom django.views.generic import Viewclass Index (View ): def get (self, request ): return render_to_response(request, 'index.html' )
传递数据给页面
{'key': 'value'}
:通过字典的形式传递给页面
<project_name>/<app_name>/views.py 1 2 3 4 5 6 from .base_render import render_to_responsefrom django.views.generic import Viewclass Index (View ): def get (self, request ): return render_to_response(request, 'index.html' , data={'key' : 'value' })
页面中使用传递的数据
mako页面中传递数据方式与内置模版传递数据方式不同,通过${}
使用传递的数据
<project_name>/templates/index.html 1 2 3 4 5 6 7 8 9 10 11 12 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > </head > <body > <h1 > Hello ${key}</h1 > </body > </html >
在子应用中创建一个路由
index
:视图层定义的函数名
<project_name>/<app_name>/urls.py 1 2 3 4 5 6 from django.urls import pathfrom .views import Indexurlpatterns = [ path('' , Index.as_view()), ]
将子路由绑定到跟路由
引入include
模块
通过include()
引入子路由
<project_name>/<project_name>/urls.py 1 2 3 4 5 6 7 from django.contrib import adminfrom django.urls import path, includeurlpatterns = [ path('admin/' , admin.site.urls), path('' , include('<app_name>.urls' )), ]
在模版中直接写Python代码
${}
不仅可以在页面显示传递过来的数据,还可以在页面显示当前页面的Python变量
1 2 3 4 <%! from django.conf import settings %> ${settings.TEMPLATES[0]['DIRS'][0]}
完成 参考文献 哔哩哔哩——图灵学院教程 CSDN——测开小菜鸟 CSDN——stay down CSDN——Ethanhuyi CSDN——风情小皮球