# 初始化后
使用 idea 生成的目录结构
- Django 是项目的名称
- init.py:一个空文件,告诉 python 该目录是一个 python 包
- asgi.py:一个 ASGI 兼容的 Web 服务器的入口,以便运行项目
- setting.py: 该 Django 项目的设置 / 配置
- urls.py: 项目的主路由配置 ——HTTP 请求进入 Django 的时候,优先此文件
- wsgi.py: 一个 WSGI 兼容的 Web 服务器的入口,以便运行项目(WEB 服务网关的配置项目)
# Setting.py 相关配置
- SECRET_KEY
引用一段 Flask Web Development 中的内容:
SECRET_KEY 配置变量是通用密钥,可在 Flask 和多个第三方扩展中使用。如其名所示,加密的强度取决于变量值的机密度。不同的程序要使用不同的密钥,而且要保证其他人不知道你所用的字符串.
SECRET_KEY 的作用主要是提供一个值做各种 HASH, 我没有实际研究过源码,不同框架和第三方库的功能也不尽相同,我不能给出准确的答案,但是主要的作用应该是在其加密过程中作为算法的一个参数 (salt 或其他). 所以这个值的复杂度也就影响到了数据传输和存储时的复杂度.
另外,考虑到安全性,这个密钥是不建议存储在你的程序中的。最好的方法是存储在你的系统环境变量中,通过 os.getenv (key, default=None) 获得.
SECTET_KEY
在 Djanog
中使用非常广泛,基本上涉及到安全,加密等的地方都用到了
- DEBUG
这是程序启动的一种模式,如果你开启此模式(DEBUG=True),那么在我们启动程序后再修改代码并保存后就不需要重新启动,Django 会自动为我们重启项目,代码中出现 bug 那么在我们访问地址的时候,浏览器和控制台会打印错误信息。
在生产环境中是禁用 DEBUG 模式的,不然会有很大的安全隐患,需要设置 ALLOWED_HOSTS。ALLOWED_HOSTS:这个变量是用来设置以后别人只能通过这个变量中的 ip 地址或者域名来进行访问。
eg:
ALLOWED_HOSTS = []#一般放的是 host 的头部 |
这样 Django 是默认(localhost: 端口号)和(127.0.0.1: 端口号)允许这两个访问
一般在 [] 这里面会写入我们的二级域名
INSTALLED_APPS
作为查找模型,管理命令,测试和其他实用程序的所有位置的列表。
当你在项目里新建立了一个 app 的时候要到这个地方注册
eg: 在控制台输出 python manage.py startapp appname (注意要在和 manage.py 同一级目录下)
然后去项目的 setting.py 里面
这样 Django 才能找到你的 app
MIDDLEWARE
- 中间件是介于 request 和 response 处理之间的一道处理过程,用于全局范围改变 Django 的输入和输出,简单的来说中间件是帮助我们在视图函数指向之前和执行之后都可以做一些额外的操作。
- Django 项目中默认启用了 csrf 保护,每次请求通过 csrf 中间件检查请求是否是有正确的 token 值;当用户发送请求时,通过自定义的认证中间件,判断用户是否已经登录,未登录就去登录;当用户的请求过阿里阿是,判断用户是否在白名单或者黑名单内。
- ROOT_URLCONF
路由配置路径从什么地方开始找
- TEMPLATES
参数说明:
- BACKEND:指定模板引擎
- DIRS:模板搜索目录
- APP_DIRS:是否要在应用中的 templates 文件夹中搜索模板文件
- OPTIONS:有关模板选项
- DATABASES
连接数据库相关配置
详细请看官方文档:https://docs.djangoproject.com/en/3.2/ref/settings/#databases
LANGUAGE_CODE:语言设置
TIME_ZONE: 时区设置
- 视图和 URL 的设置
在 Django 目录下创建一个 views.py 文件
将 URL 与视图函数绑定
说明:
Path()函数可以接收 4 个参数,分别是两个必选参数:route、view 和两个可选参数:kwargs、name
语法格式:path(route,view,kwargs,name)
- Route: 字符串,表示 URL 的规则,与之匹配的 URL 会执行对应的第二个参数 view
- View:用来执行与正则表达式匹配的 URL 请求
- Kwargs:试图使用的字典类型的参数
- Name:用来反向获取 URL
上面的输出 Hello World 是使用 HttpResponse () 来输出的,这种方式将数据和视图混在一起,不符合 Django 的 MVC 思想
使用模板来输出 Hello World
在 Django 目录下新建一个 templates 文件夹来存放 html 文件
新建一个 html 文件命名为:runoob.html,内容如下:
然后要向 django 说明模板文件的路径,修改 setting.py,修改 TEMPLATES 中的 DIRS 为 [os.path.join (BASE_DIR,’templates’)],如下:
然后去修改 views.py ,增加一个新的对象,用于向模板提交数据
这样就完成了使用模板来输出数据,从而实现数据和视图的分离
# 模板标签
# 变量(模板语法)
<!-- 花括号之间不用空格 --> | |
view:{'HTML变量名':'views变量名'} | |
HTML:{ {变量名} } |
例子:
Django/views.py
def runoob(request): | |
view_anme="努力学习天天向上!" | |
return render(request, 'runoob.html', {'name':view_anme}) |
templates 中的 runoob.html
<!-- 花括号之间不用空格 --> | |
<h1>{ { name } }</h1> |
然后再去访问 localhost:8000/runoob
# 列表
在 templates 中的 runoob.html 中,可以使用 . 来索引下标取出对应的元素。
Django/views.py
def eg_list(request): | |
view_list = ["first", "second", "third"] | |
return render(request, "eg_list.html",{"view_list":view_list}) |
templates 中的 eg_list.html
<!-- 花括号之间不用空格 --> | |
<h1>{ { view_list } }</h1> | |
<h1>{ { view_list.0 } }</h1> |
加了新的访问连接需要配置 urls.py 文件
urlpatterns = [ | |
path('hello/', views.hello), | |
path('runoob/', views.runoob), | |
path('eg_list',views.eg_list),#这个是新增的 | |
] |
然后访问 localhost:8000/eg_list
# 字典
在 templates 中字典和列表一样可以是用索引来取出对应的值
Django/views.py
def eg_dictionary(request): | |
view_dictionary = {"name": "ZhangSan","sex":"man"} | |
return render(request, "eg_dictionary.html",view_dictionary) |
templates 中的 eg_dictionary.html
<!-- 花括号之间不用空格 --> | |
<h1>{ { view_dictionary } }</h1> | |
<h1>{ { view_dictionary.name } }</h1> | |
<h1>{ { view_dictionary.sex } }</h1> |
Django/urls.py
urlpatterns = [ | |
path('hello/', views.hello), | |
path('runoob/', views.runoob), | |
path('eg_list/', views.eg_list), | |
path('eg_dictionary/', views.eg_dictionary) #这个是新增的 | |
] |
然后访问 localhost:8000/eg_dictionary
# 过滤器
{ { 变量名 | 过滤器:可选参数 } } |
模板过滤器可以在变量被显示前修改它,过滤器使用管道字符,如下所示:
{ { name|lower } } |
变量被过滤器 lower 处理后,文档大写转换文本为小写。
过滤管道可以被套接 ,既是说,一个过滤器管道的输出又可以作为下一个管道的输入:
{ { my_list|first|upper } } |
# safe
将字符串标记为安全,不需要转义。
要保证 views.py 传过来的数据绝对安全,才能用 safe。
一般情况下 Django 会将我们传入的数据直接转义成字符格式。
和后端 views.py 的 mark_safe 效果相同。
Django 会自动对 views.py 传到 HTML 文件中的标签语法进行转义,令其语义失效。加 safe 过滤器是告诉 Django 该数据是安全的,不必对其进行转义,可以让该数据语义生效。
# if/else 标签
基本语法格式如下:({和 % 之间不需要空格)
{ % if condition % } | |
... display | |
{ % endif % } |
或者:
{ % if condition1 %} | |
... display 1 | |
{ % elif condition2 %} | |
... display 2 | |
{ % else %} | |
... display 3 | |
{ % endif %} |
根据条件判断是否输出。if/else 支持嵌套。
{ % if % } |
标签接受 and , or 或者 not 关键字来对多个变量做判断 ,或者对变量取反( not )。
# for 标签
{ % for %} |
允许我们在一个序列上迭代。
与 Python 的 for 语句的情形类似,循环语法是 for X in Y ,Y 是要迭代的序列而 X 是在每一个特定的循环中使用的变量名称。
每一次循环中,模板系统会渲染在
{ % for % }和{ % endfor % } |
之间的所有内容。
# 注释标签
Django 注释使用 。
python
{ # 这是一个注释 #} |
# include 标签
{ % include %} |
标签允许在模板中包含其它的模板的内容。
下面这个例子都包含了 nav.html 模板:
{ % include "nav.html" %} |
# csrf_token
csrf_token 用于 form 表单中,作用是跨站请求伪造保护。
如果不用{ % csrf_token %}标签,在用 form 表单时,要再次跳转页面会报403权限错误。 | |
用了{ % csrf_token %}标签,在 form 表单提交数据时,才会成功。 |
解析:
首先,向服务器发送请求,获取登录页面,此时中间件 csrf 会自动生成一个隐藏 input 标签,该标签里的 value 属性的值是一个随机的字符串,用户获取到登录页面的同时也获取到了这个隐藏的 input 标签。
然后,等用户需要用到 form 表单提交数据的时候,会携带这个 input 标签一起提交给中间件 csrf,原因是 form 表单提交数据时,会包括所有的 input 标签,中间件 csrf 接收到数据时,会判断,这个随机字符串是不是第一次它发给用户的那个,如果是,则数据提交成功,如果不是,则返回 403 权限错误。
# 配置静态文件
- 在项目根目录下创建 statics 目录。
- 写配置
在 settings.py 文件的最下方配置找到 STATIC_URL
在其下方添加以下配置:
STATIC_URL = '/static/' # 别名 | |
STATICFILES_DIRS = [ | |
os.path.join(BASE_DIR, "statics"), | |
] |
在此目录下可以存放我们的 css 目录,js 目录,images 目录,plugins 目录, 分别放 css 文件,js 文件,图片,插件等等静态资源。
# 模板继承
模板可以用继承的方式来实现复用,减少冗余内容。
网页的头部和尾部内容一般都是一致的,我们就可以通过模板继承来实现复用。
父模板用于放置可重复利用的内容,子模板继承父模板的内容,并放置自己的内容
# 父模板
标签 block…endblock: 父模板中的预留区域,该区域留给子模板填充差异性的内容,不同预留区域名字不能相同。
{ % block 名称 %} | |
预留给子模板的区域,可以设置设置默认内容 | |
{ % endblock 名称 %} |
# 子模板
子模板使用标签 extends 继承父模板:
{ % extends "父模板路径"%} |
子模板如果没有设置父模板预留区域的内容,则使用在父模板设置的默认内容,当然也可以都不设置,就为空。
子模板设置父模板预留区域的内容:
{ % block 名称 % } | |
内容 | |
{ % endblock 名称 %} |
# Django 模型
Django 模型使用自带的 ORM。
对象关系映射(Object Relational Mapping,简称 ORM )用于实现面向对象编程语言里不同类型系统的数据之间的转换。
ORM 在业务逻辑层和数据库层之间充当了桥梁的作用。
ORM 是通过使用描述对象和数据库之间的映射的元数据,将程序中的对象自动持久化到数据库中。
ORM 的好处:
- 可以提高我们的开发效率
- 不同的数据库可以平滑切换
ORM 的缺点:
- ORM 代码转换为 SQL 语句时,需要花费一定的时间,执行效率会有所降低。
- 使用多了 ORM,会降低编写 SQL 的能力
ORM 的解析过程:
ORM 会将 Python 代码转成为 SQL 语句。
SQL 语句通过 pymysql 传送到数据库服务端。
在数据库中执行 SQL 语句并将结果返回。
# 配置数据库
Django 默认使用的是 sqlite3(是一个轻量级的数据库)
我们要连接的是 MySQL 数据库
- 首先创建一个数据库
create database 数据库名称 default charset=utf8; # 防止编码问题,指定为 utf8
- 然后再 setting.py 里面找到 DATABASES
DATABASES = { | |
'default': { | |
'ENGINE': 'django.db.backends.mysql', | |
'NAME': '数据库的名称', | |
'USER': '用户名', | |
'PASSWORD': '密码', | |
'HOST': '访问的数据库主机IP地址', | |
'PORT': '默认的MySQL端口', | |
} | |
} |
- 在项目的 setting.py 同级目录下的–init–.py 中引入模块和进行配置
import pymysql#确保你有这个库,没有的话使用 pip 进行安装 | |
pymysql.install_as_MySQLdb() |
# 定义模型
你之前创建的 APP 的目录结构:
修改 models.py 文件,代码如下:
# models.py | |
from django.db import models | |
class Test(models.Model): | |
name = models.CharField(max_length=20) |
以上的类名代表了数据库表名,且继承了 models.Model,类里面的字段代表数据表中的字段 (name),数据类型则由 CharField(相当于 varchar)、DateField(相当于 datetime), max_length 参数限定长度。
编辑好你的 models 后在 cmd 中运行:
python manage.py makemigrations # 让 Django 知道我们在我们的模型有一些变更
python manage.py migrate # 创建表结构
(在此可能出现的错误是:app 里面的 models 并没有修改,则命令不会运行成功,在你编辑好 models 后运行就没有问题了)