Django总结一
HTTPRequest与HTTPresponse 一、 1、互联网两台机器之间通行:ip、端口、协议
- 协议
- HTTP (80)
- HTTPS (443) 2、浏览器输入URL一回车返回页面发生了什么?
- 域名 -> DNS解析 -->ip地址 -> 找到服务端 ->服务端返回消息 -> 浏览器
- 浏览器 <-> 服务器
- 服务器把 写好的HTML页面,返回给浏览器,浏览器按照HTML格式渲染
「 」 3、请求和相应
- HTTP协议的特点:
- 浏览器给服务端发消息的过程叫请求(request)
- 服务器给浏览器回复消息的过程叫响应(response) - 请求和相应的消息都必须遵循一个固定的格式 4、python中Web框架分类
- a、收发socket消息,按照HTTP协议解析消息 Web服务程序 wsgiref(模块)、gunicorn、uWSGI
- b、字符串替换,用来实现动态网页
- c、业务逻辑处理 Web应用程序 1- 自己实现abc的
- Tronado
2- 自己实现bc使用别人的a
- Django
3- 自己实现c使用别人的ab
- Flask
5、Web服务程序 <- WSGI协议 -> Web应用程序 5.5、Django版本
- LTS版本 (Long Team support) 6、创建第一个Django项目 安装: pip install django==1.11.11
pip install django==1.11.11 -i 指定源 - 1、命令行 Django-admin startproject first_Django
- 2、Pycharm创建
- file -> new Project ->右侧选Django -> 选好路径 ->选好环境 -> 名字app -> 在新的窗口打开文件
- 3、启动项目
- 命令行启动(切换到项目的根目录)
- python manage.py runserver 127.0.0.1:8090(改端口这样指定)
- pycharm启动
- 框中选项为项目名->让后点击启动按钮(右上角)(如果想改就在旁边点编辑-就可以改端口等) - 目录介绍
- 和项目名一样的是根目录
-
---------------------
- 先来一份自己的理解
- 1、(与我们所创建文件名一致的目录)根目录
- manage.py
- 这是启动文件,程序入口。
- settings.py
- 包含了项目的一些设置,包括数据库信息、调试标志以及其他的一些工作的变量。
- BASE_DIR = 项目的根目录
- TIMELATES = templates去哪找
- DATABASES = 数据库
- 静态文件配置
- STATIC_URL = '/static/' # 请别名
- STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'),] # 配置去static下找静态文件
- urls.py
- 路径与视图函数的映射关系 - 2、templates - 这个文件夹存放的是HTML文件
- 3、static - 这个文件夹是存放静态文件,需要自己配置,用的时候的导入时用
/static/.. 来引入所用的静态文件
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/ # 这个static就代表了下面的路径 (寻找的时候就是去static下面的路径中挨个找)
STATIC_URL = '/static/' # 起别名, HTML中找静态文件都要以这个别名开始 (找到别名后就去这个别名的配置比文件中找对应的文件) # 这个常量是固定格式
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
] 7、项目流程
- 先输入url
- 去Django的urls中匹配urlpatterns->匹配上调用后面匹配的函数->去找对应的函数
- 找到执行的函数->Django调用要执行的函数给函数传一个request参数,所有和请求相关的数据 都在request中
- render去templates文件夹找到HTML文件,打开读取内容,按照http响应格式给浏览器返回读取的内容
- 浏览器收到Django返回的响应消息,按照HTML格式显示这个消息 其他:
- from django.shortcuts import HttpResponse, render
- HttpResponse (封装了协议头等-有待商议)
- render (渲染) - 文件的上传(form表单的提交, 必须用POST)
def index(request):
print(request.GET)
print(request.POST)
print(request.FILES) for item in request.FILES:
fileobj = request.FILES.get(item)
f = open('upload/%s' % fileobj.name, 'wb')
item_file = fileobj.chunks()
for line in item_file:
f.write(line)
f.close() return HttpResponse("成功")
- form表单上传文件时需要注意的事情
- action 最后加 / 或者 修改settings:APPEND_SLASH=False
- method 必须为post
- enctype = “multipart/form-data” 必须写 - 指定IP登录
默认IP和端口
python manage.py runserver
指定端口:
python manage.py runserver 192.168.12.12:8080
此时会报错,我们需要修改配置文件:
修改settings.py,将192.168.12.12添加到ALLOWED_HOSTS中
ALLOWED_HOSTS=['172.31.169.182','127.0.0.1','192.168.1.50','192.168.1.115']
也可以将ALLOWED_HOSTS改成通配符 *
ALLOWED_HOSTS = ["*"] 二、 1、表单的提交(登录)
- submit -> action -> 对应函数(参数request(数据信息))-> 处理
注意:必须要有name属性 *****
- 提交到服务器的是QueryDict对象,可以通过get获取值 2、form表单提交的三个要素
- form标签必须有action和method属性
- 所有获取用户输入的标签必须放在form表单中,必须有name属性(input,select,textarea)
- 必须有submit按钮 3、redirect 跳转,改变方向
- 跳转到别人的页面,自己的页面
- 跳转比人页面
redirect("https://baidu.com")
- 跳转自己页面
redirect("/相对路径/") 4、Django必会三件套 from django.shortcuts import
- HttpRequest 返回一个指定的字符串
(把字符串转为而二进制,然后按照HTTP响应格式要求返回)
- render 返回一个HTML文件 HTML文件 模板语言
(第一个参数为request, 第二个参数为render的页面,第三个参数为字典,将render页面中的特殊符号替换{字典的键为html的变量,值为给页面展示的值})
- redirect 跳转 路径 URL
(redirect(/index/) -> 在同网站不同地址间跳转(返回重定向响应)
redirect('https://wwww.baidu.com') -> 访问指定的网址) 5、request相关属性 (所有和请求相关的数据都封装在request对象中)
- POST 取到POST提交的数据(form表单提交的)
- GET 取到URL携带的参数
- method 当前这次请求的方法(GET/POST) 6、Django的模板语言
{{ 变量 }} 7、Django项目project
- app(应用) -> 不同的功能放在不同的app中
- 命令 :
- 创建app
python manage.py startapp app01(应用名)
- 注册app(告诉Django创建了app)
在settings中的 INSTALLED_APPS 添加新创建的app(app名.apps.apps中的类) 8、程序链接mysql
- 使用pymysql模块
- 导入pymysql
- 创建链接
- 获取执行命令的游标
- 用游标执行SQL语句
- 获取SQL语句的执行结果
- 关闭游标
- 关闭链接 - ORM - Object Relationship Mapping (对象关系映射)
- 这时,创建一种工具 帮助我们翻译SQL语句(ORM - 面向对象的思想)
- 优点
- 开发效率高
- 开发不用直接写SQL语句
- 缺点
- 执行效率低 - 对应关系
ORM DB 类 数据表
属性 字段
对象 数据行 - Django项目project
- app(应用) -> 不同的功能放在不同的app中
- 命令 :
- 创建app
python manage.py startapp app01(应用名)
- 告诉Django创建了app
在settings中的 INSTALLED_APPS 添加新创建的app(app名.apps.apps中的类)
- Django中ORM使用
- 用处:
- 操作数据表
- 操作数据行
- 使用
- 手动创建数据库
- 告诉Django连那个数据库
- settings中配置DATABASES
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 链接数据库的类型
'NAME': 'db', # 链接数据库的名字
'HOST': '127.0.0.1', # 数据库主机地址
'PORT': 3306, # 数据库端口
'USER': 'root', # 数据库用户名
'PASSWORD': '', # 数据库密码
}
} - 用什么链接数据库?
- 利用第三方包 pymysql 和 MySQLdb(py2中)
- 告诉Django用pymysql模块代替默认的MySQLdb链接MySQL数据库
和settings.py同级的__init__.py文件,写上
import pymysql
pymysql.install_as_MySQLdb() - 在app/models.py的文件中创建类
类必须继承models.Model - 两个命令
- python manage.py makemigrations -> 生成脚本文件存放在app文件夹应用下的migrations文件夹中(相当于拿个小本本把models.py的变更记录下来)
- python manage.py migrate -> 把上面的变更记录翻译成sql语句,去数据库执行 - ORM查询
modules.User.object.filter(email='', pwd='') 三、 1、图书管理系统
- 出版社
id name
- 作者
id name
- 书
id title 出版社_id
- 书_作者关系表
id 书_id 作者_id 2.ORM增删改查
models.表名.object./filter()/all()/create()
- filter() 按照指定内容筛选 (字段=值) 放回一个列表
- all() 查询出数据库所有信息(属性order_by(id)排序) 返回一个列表
- create() 向数据库添加信息 (字段=值)创建一个对象 返回一个创建的对象
- get() 返回一个对象
- filter(id='').delete() 删除
- obj = 类名.object.get(id='')
obj.name = '新值' 修改对象的属性(修改数据行某个字段的值)
obj.save() 把修改同步到数据库 3、模板语言
- for循环
{% for i in ret %}
{{ i }}
{{ forloop.counter }} for循环从1开始计数
{{ forloop.counter0 }} for循环从0开始计数
{% endfor %} 总结:ORM的 查、增、删、改 - 查
- client
- 有一个展示页面(xxx_show.html)
- 这一个页面一输入执行后,get请求向server端发送
- 这个展示页面有添加按钮、删除按钮、编辑按钮
- 这个页面要展示内容
- 是server端收到第一次的get请求而做出的response
- 页面需要用到模板语言for循环
{% for i in result %}
{{ i.xx }} #获取result中的每个值(也就是server端传来的东西)
{% endfor %}
- server
- 首先会收到一开始访问页面的GET请求
- 收到请求后到urls中找匹配的url,找到对应的url后,执行后面所对应的视图函数
- 找到对应的视图函数后就行执行响应的逻辑,也就是拿出数据库中的东西,发送给server
- 可以通过 models.表名.objects.all() 获取数据库这张表中的所有内容(返回一个列表)
- data = models.表名.objects.all()
- 拿到数据后将这些数据给展示(通过render方法)
- return render(request, 'xxx_show.html', 'result':data)
#这里的result就是要传给xxx_show.html的一个变量(其中的值就是data的数据) - 增
- client
- 有一个展示页面(xxx_show.html)
- 这个页面有一个添加按钮(a标签)
- 点击这个按钮(a标签),client会发送一个get请求,会用a标签的路径去访问server
- 这时会跳转到a标签所指的url(/add_xxx/)
- 然后server给出response(这里的业务逻辑就都得在server)
- 第一次get请求server会返回一个add_xxx.html页面
- 这是可以添加数据
- 用form表单,action为add_xxx这个url,method为post
- 点击提交之后client向server发送一个请求
- server收到请求后回复一个response - server
- 收到a标签跳转的url(get请求响应)
- 收到add_xxx这个url进入urls中匹配,匹配到就去他对应的视图函数
- 这个视图函数处理响应的业务逻辑
- 首先第一次来的时候时GET请求,这个时候应该将add_xxx.html这个页面返回给client
- return render(request, add_xxx.html)
- 然后server收到提交的POST请求
- 从POST请求中拿出client发送来的数据
- data = request.POST.get("input标签的name")
- 将数据存入数据库
- models.tablename.objects.create(字段=data)
- 将数据库中的结果重新返回(也就是xxx_show。html)
- return redirect('/xxx_show/') - 删
- client
- 有一个展示页面(xxx_show.html)
- 有一个删除按钮(a标签)
- 点击这个按钮(a标签),client会发送一个get请求,会用a标签的路径去访问server
- 点击这个a标签(按钮)会跳转到他对应的url('/del_xxx/')
- 这时需要将这个按钮对应的数据传到server,server才能按照这个数据去删除
- <a href="/del_xxx/?id={{ i.id }}"><button>del</button></a>
- ?是一个固定格式,而后面就是一些参数(服务端要用的一些参数)
- server收到这个参数后就可以按照他进行相应的操作
- 然后server会返回一个response(这里的业务逻辑在server端) - server
- 收到a标签跳转的url(get请求响应)
- 收到del_xxx这个url进入urls中匹配,匹配到就去他对应的视图函数
- 这个视图函数处理响应的业务逻辑
- 通过client传来的参数来锁定删除的id
- del_id = request.GET.get("id")
- 删除数据库中del_id对应的值
- models.tablename.objects.fileter(id=del_id).delete()
- 删除成功后返回删除后的页面('/xxx_show/')(重定性)
- return redirect('/xxx_show/') - 改
- client
- 有一个展示页面(xxx_show.html)
- 有一个编辑(edit)按钮(a标签)
- 点击这个按钮(a标签),client会发送一个get请求,会用a标签的路径去访问server
- 点击这个a标签(按钮)会跳转到他对应的url('/edit_xxx/')
- 这时需要将这个按钮对应的数据传到server,server才能更改这个数据
- <a href="/edit_xxx/?id={{ i.id }}"><button>del</button></a>
- ?是一个固定格式,而后面就是一些参数(服务端要用的一些参数)
- server收到这个参数后就可以按照他进行相应的操作
- 然后server会返回一个response(这里的业务逻辑在server端)
- 第一次发送get请求时会跳转到edit_xxx.html这个页面,这里面是该行对应的数据
- 第二次发送post请求,这里面会有修改后的数据然后发送给server处理
- <form action="/edit_press/?id={{ result.id }}" method="post">
<input type="text" name="updata_name" value="{{ result.name }}">
<input type="submit">
</form> - input中的数据都是在server查出的数据展现出来的
- id是通过点击edit按钮的时候将这个按钮对应的id值记录了下来 - 处理完后返回原来的xxx_show - server
- 收到a标签跳转的url(get请求响应)
- 收到edit_xxx这个url进入urls中匹配,匹配到就去他对应的视图函数
- 这个视图函数处理响应的业务逻辑
- 第一遍的GET请求
- 通过client传来的参数来锁定编辑(edit)的id
- edit_id = request.GET.get("id")
- 会返回当前编辑行的内容
- 从数据库中拿出这个值,将这个值展现在edit_xxx.html页面中
- result = models.tablename.objects.filter(id="")[0]
- 返回当前编辑的页面
- return render(request, 'edit_xxx.html', {'resule': result}) - 第二遍请求是提交数据后的POST请求,
- form表单中的action为这个编辑页面,
- 这个页面后面的参数为第一次get请求得到的数据
- 可以通过GET方法来获取URL上的参数的值 - 这个时候form表单对应的url来urls中找对应的视图函数
- 这个视图函数就会执行POST请求的逻辑
- 用这个新数据把数据库中的旧数据掩盖
- 获取更改后的值
- data = request.POST.get("updata_name")
- 更改数据库中的值
- 从数据库找到id对应的对象
- #这里的id就是第一次点击编辑的时候得到的id值(--对应的)
- new_obj = models.tablename.objects.filter(id='edit_id')[0]
- new_obj.name = data #将新的值赋值给数据库中的变量
- new_obj.save() #这个事务必须save数据库中的数据才会更改 - 更改完成后返回,xxx_show页面
- return redirect('/xxx_show/') 注意:
通过GET来获取URL中的值(和请求无关),POST获取表单提交的值。 四、 1、 a标签
- href属性
- 相对路径
- 绝对路径
- target = "_blank" 跳转到新页面, 不写默认覆盖自己的页面
- 锚点(同网站标签的跳转(#id名)) 2、 # 出版社
class Press(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32) def __str__(self): # print的时候测试使用
return self.name # 书
class Book(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
# Django1.1默认就是级联删除,2.0必须指定
# 可以通过字符串的反射找Press,如果在代码前面就可以直接用,to=关联的表名
# 外键字段ORM会给他默认加一个_id (加上_id后他的值就是对应关联表的主键值)
press = models.ForeignKey(to='Press', on_delete=models.CASCADE) - 一对多
- 一个出版社对应多本书(外键设置在多的一方)
- 书的属性有一个外键为链接出版社的press_id 书籍的增删改查
- 增 - 删 - 改 - 查 注意:
- 增的时候,出版社就是表中的固定出版社,用一个select标签将数据展示,而不是用户自己填
<form action="/add_book/" method="post">
书名:<input type="text" name="book_title">
<select name="title_name" id="">
{% for press in data %}
<option value="{{ press.id }}">
{{ press.name }}
</option>
{% endfor %}
</select>
<input type="submit">
</form>
- 改的实时,出版社的内容需要先选定好。需要用模板语言来判断
# 这中情况form表单不指定action他默认会提交当前的页面(这是的页面是点击编辑时的页面)
<form action="/edit_book/?id={{ data.id }}" method="post">
<input type="text" name="title_name" value="{{ data.title }}">
<select name="press_name" id="">
{% for press in data_list %}
{% if data.press == press %}
<option value="{{ press.id }}" selected>
</option>
{{ press.name }}
{% else %}
<option value="{{ press.id }}">
{{ press.name }}
</option>
{% endif %}
{% endfor %}
</select>
<input type="submit">
</form> 五、
- 给数据库中已经存在的表添加另外一个字段,ORM不知道如何处理
- 1) 输入 1 会让用户自己填写一个默认值(在命令行中)
- 2) 输入 2 自己在ORMclass中指定字段自己加默认值(退出命令行)在modules中修改
- null = True
- default = 默认值 1. 多对多关系
作者 <--> 书籍
1. 表结构设计
1. SQL版
-- 创建作者表
create table author(
id int primary key auto_increment,
name varchar(32) not null
); -- 创建作者和书的关系表
create table author2book(
id int primary key auto_increment,
author_id int not null,
book_id int not null,
constraint fk_author foreign key (author_id) references author(id) on delete cascade on update cascade,
constraint fk_book foreign key (book_id) references book(id) on delete cascade on update cascade
); 2. ORM版
1. 第一版:
自己创建第三张表
2. 第二版
让ORM帮我们创建第三张表
models.ManyToManyField()
3. 第三版
待补充...(ORM进阶操作的时候)
2. 作者的增删改查
1. 查询
author_obj.books --> 得到的只是一个关联关系,并不能拿到数据
author_obj.books.all() --> 得到和我这个作者关联的所有书籍对象列表
2. 添加
1. getlist() # 得到同一name的列表对象
2. add()
3. set() 3. 删除 4. 编辑
1. 模板语言中
{% if book in author.books.all %}
2. ORM编辑多对多
1. 不能直接操作第三张关系表
2. 借助ORM给提供的方法
1. all()
2. add(id1,id2)
3. set([id1, id2])
4. clear()
3. Django模板语言
1. for循环
1. forloop.last
{% if forloop.last %}
...
2. empty
{% for i in x %}
...
{% empty %}
...
{% endfor %}
4. 上传文件
form表单上传文件
# 文件的上传
def index(request):
print(request.FILES) # 上传的文件列表对象
for item in request.FILES:
fileobj = request.FILES.get(item) # 挨个获取列表中每个对象
f = open('upload/%s' % fileobj.name, 'wb')
item_file = fileobj.chunks()
for line in item_file:
f.write(line)
f.close() return HttpResponse("成功") 2. 学生管理系统
- 老师 和 班级 是多对多的关系 六、Django模板系统(模板语言)(very important)
- 基础语法
- 跟变量相关 {{ }}
在Django的模板语言中按此语法使用:{{ 变量名 }}。 当模版引擎遇到一个变量,它将计算这个变量,然后用结果替换掉它本身。
变量的命名包括任何字母数字以及下划线 ("_")的组合。 变量名称中不能有空格或标点符号。
点(.)在模板语言中有特殊的含义。当模版系统遇到点("."),它将以这样的顺序查询: ***** 属性->方法->索引
字典查询(Dictionary lookup)
属性或方法查询(Attribute or method lookup)
数字索引查询(Numeric index lookup) 注意事项: 如果计算结果的值是可调用的,它将被无参数的调用。 调用的结果将成为模版的值。
如果使用的变量不存在, 模版系统将插入 string_if_invalid 选项的值, 它被默认设置为'' (空字符串) 。 {# 取l中的第一个参数 #}
{{ l.0 }}
{# 取字典中key的值 #}
{{ d.name }}
{# 取对象的name属性 #}
{{ person_list.0.name }}
{# .操作只能调用不带参数的方法 #}
{{ person_list.0.dream }} - Filter过滤器
在Django的模板语言中,通过使用 过滤器 来改变变量的显示。
过滤器的语法: {{ value|filter_name:参数 }} 使用管道符"|"来应用过滤器。 例如:{{ name|lower }}会将name变量应用lower过滤器之后再显示它的值。lower在这里的作用是将文本全都变成小写。 注意事项: 过滤器支持“链式”操作。即一个过滤器的输出作为另一个过滤器的输入。
过滤器可以接受参数,例如:{{ sss|truncatewords:30 }},这将显示sss的前30个词。
过滤器参数包含空格的话,必须用引号包裹起来。比如使用逗号和空格去连接一个列表中的元素,如:{{ list|join:', ' }}
'|'左右 没有空格没有空格没有空格 ****** Django的模板语言中提供了大约六十个内置过滤器 - 一些常用的过滤器
- default
如果一个变量是false或者为空,使用给定的默认值。 否则,使用变量的值。 {{ value|default:"nothing"}}
如果value没有传值或者值为空的话就显示nothing
注:TEMPLATES的OPTIONS可以增加一个选项:string_if_invalid:'找不到',可以替代default的的作用。 - length
返回值的长度,作用于字符串和列表。 {{ value|length }}
返回value的长度,如 value=['a', 'b', 'c', 'd']的话,就显示4. - filesizeformat
将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。例如: {{ value|filesizeformat }}
如果 value 是 1234567890,输出将会是 1.1GB。 - slice
切片 {{value|slice:"2:-1"}}
- add
给变量加参数 {{ value|add:"" }}
value是数字4,则输出结果为6。 {{ first|add:second }}
如果first是 [1,.2,3] ,second是 [4,5,6] ,那输出结果是 [1,2,3,4,5,6] 。 - data
格式化 {{ value|date:"Y-m-d H:i:s"}}
可用的参数:
格式化字符 描述 示例输出
a 'a.m.'或'p.m.'(请注意,这与PHP的输出略有不同,因为这包括符合Associated Press风格的期间) 'a.m.'
A 'AM'或'PM'。 'AM'
b 月,文字,3个字母,小写。 'jan'
B 未实现。
c ISO 8601格式。 (注意:与其他格式化程序不同,例如“Z”,“O”或“r”,如果值为naive datetime,则“c”格式化程序不会添加时区偏移量(请参阅datetime.tzinfo) 。 2008-01-02T10:30:00.000123+02:00或2008-01-02T10:30:00.000123如果datetime是天真的
d 月的日子,带前导零的2位数字。 ''到''
D 一周中的文字,3个字母。 “星期五”
e 时区名称 可能是任何格式,或者可能返回一个空字符串,具体取决于datetime。 ''、'GMT'、'-500'、'US/Eastern'等
E 月份,特定地区的替代表示通常用于长日期表示。 'listopada'(对于波兰语区域,而不是'Listopad')
f 时间,在12小时的小时和分钟内,如果它们为零,则分钟停留。 专有扩展。 '','1:30'
F 月,文,长。 '一月'
g 小时,12小时格式,无前导零。 ''到''
G 小时,24小时格式,无前导零。 ''到''
h 小时,12小时格式。 ''到''
H 小时,24小时格式。 ''到''
i 分钟。 ''到''
I 夏令时间,无论是否生效。 ''或''
j 没有前导零的月份的日子。 ''到''
l 星期几,文字长。 '星期五'
L 布尔值是否是一个闰年。 True或False
m 月,2位数字带前导零。 ''到''
M 月,文字,3个字母。 “扬”
n 月无前导零。 ''到''
N 美联社风格的月份缩写。 专有扩展。 'Jan.','Feb.','March','May'
o ISO-8601周编号,对应于使用闰年的ISO-8601周数(W)。 对于更常见的年份格式,请参见Y。 '1999年'
O 与格林威治时间的差异在几小时内。 '+0200'
P 时间为12小时,分钟和'a.m。'/'p.m。',如果为零,分钟停留,特殊情况下的字符串“午夜”和“中午”。 专有扩展。 '1 am','1:30 pm' / t3>,'midnight','noon','12:30 pm' / T10>
r RFC 5322格式化日期。 'Thu, 21 Dec 2000 16:01:07 +0200'
s 秒,带前导零的2位数字。 ''到''
S 一个月的英文序数后缀,2个字符。 'st','nd','rd'或'th'
t 给定月份的天数。 28 to 31
T 本机的时区。 'EST','MDT'
u 微秒。 000000 to 999999
U 自Unix Epoch以来的二分之一(1970年1月1日00:00:00 UTC)。
w 星期几,数字无前导零。 ''(星期日)至''(星期六)
W ISO-8601周数,周数从星期一开始。 1,53
y 年份,2位数字。 ''
Y 年,4位数。 '1999年'
z 一年中的日子 0到365
Z 时区偏移量,单位为秒。 UTC以西时区的偏移量总是为负数,对于UTC以东时,它们总是为正。 -43200到43200 - safe
Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。
但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的
文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,
如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有
两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安
全的不必转义。 比如: value = "<a href='#'>点我</a>"
{{ value|safe}} - truncchars
如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。 参数:截断的字符数 {{ value|truncatechars:9}} - truncatewords
在一定数量的字后截断字符串。 {{ value|truncatewords:9}} - cut
移除value中所有的与给出的变量相同的字符串 {{ value|cut:' ' }}
如果value为'i love you',那么将输出'iloveyou'. - join
使用字符串连接列表,例如Python的str.join(list) - timesince
将日期格式设为自该日期起的时间(例如,“4天,6小时”)。 采用一个可选参数,它是一个包含用作比较点的日期的变量(不带参数,比较点为现在)。
例如,如果blog_date是表示2006年6月1日午夜的日期实例,并且comment_date是2006年6月1日08:00的日期实例,则以下将返回“8小时”: {{ blog_date|timesince:comment_date }}
分钟是所使用的最小单位,对于相对于比较点的未来的任何日期,将返回“0分钟”。 - timeuntil
似于timesince,除了它测量从现在开始直到给定日期或日期时间的时间。
例如,如果今天是2006年6月1日,而conference_date是保留2006年6月29日的日期实例,则{{ conference_date | timeuntil }}将返回“4周”。 使用可选参数,它是一个包含用作比较点的日期(而不是现在)的变量。 如果from_date包含2006年6月22日,则以下内容将返回“1周”: {{ conference_date|timeuntil:from_date }} - 自定义filter
- 自定义过滤器只是带有一个或两个参数的Python函数: 变量(输入)的值 - -不一定是一个字符串
参数的值 - 这可以有一个默认值,或完全省略
例如,在过滤器{{var | foo:'bar'}}中,过滤器foo将传递变量var和参数“bar”。 - 创建 (步骤)
- 先在app目录下创建一个templatetagspython包(名字必须这个)
- 在目录中创建一个py文件
- 在py文件中按照固定的格式自定义一个filter(就是一个函数)
- 需要先导入 from django import template
# 固定写法,生成一个注册实例对象
register = template.Library() @register.filter() # 告诉Django的模板语言我现在注册一个自定义的filter
def add_str():pass # 第一个参数是变量名, 第二个参数为参数(最多一个) - 使用:
- 重启DJango项目
- 在HTML页面中:{% load python文件名 %}
- {{ name|add_str:'好人啊' }} - 例子:
- 自定义过滤器只是带有一个或两个参数的Python函数: 变量(输入)的值 - -不一定是一个字符串
参数的值 - 这可以有一个默认值,或完全省略
例如,在过滤器{{var | foo:“bar”}}中,过滤器foo将传递变量var和参数“bar”。 - 自定义filter代码文件摆放位置: app01/
__init__.py
models.py
templatetags/ # 在app01下面新建一个package package
__init__.py
app01_filters.py # 建一个存放自定义filter的py文件
views.py - 编写自定义filter from django import template
register = template.Library() @register.filter
def fill(value, arg):
return value.replace(" ", arg) @register.filter(name="addSB")
def add_sb(value):
return "{} SB".format(value) - 使用自定义filter {# 先导入我们自定义filter那个文件 #}
{% load app01_filters %} {# 使用我们自定义的filter #}
{{ somevariable|fill:"__" }}
{{ d.name|addSB }} - 注意:过滤器可以链接
{{ text|escape|linebreaks }} 就是一个常用的过滤器链,它编码文本内容,然后把行打破转成<p> 标签。 - 跟逻辑相关 {% %}
- 语法为:{% tag %} - for
<ul>
{% for user in user_list %}
<li>{{ user.name }}</li>
{% endfor %}
</ul> for循环可用的一些参数: Variable Description
forloop.counter 当前循环的索引值(从1开始)
forloop.counter0 当前循环的索引值(从0开始)
forloop.revcounter 当前循环的倒序索引值(从1开始)
forloop.revcounter0 当前循环的倒序索引值(从0开始)
forloop.first 当前循环是不是第一次循环(布尔值)
forloop.last 当前循环是不是最后一次循环(布尔值)
forloop.parentloop 本层循环的外层循环(是个字典) forloop是一个字典 - for ... empty
<ul>
{% for user in user_list %}
<li>{{ user.name }}</li>
{% empty %}
<li>空空如也</li>
{% endfor %}
</ul> - if,elif和else {% if user_list %}
用户人数:{{ user_list|length }}
{% elif black_list %}
黑名单数:{{ black_list|length }}
{% else %}
没有用户
{% endif %} 当然也可以只有if和else {% if user_list|length > 5 %}
七座豪华SUV
{% else %}
黄包车
{% endif %} 注:
- if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。 - with (就相当于起了一个别名)
- {% with p1.dream as dream %}
{{ dream }} # dream 代替p1.dream
{% endwith %}
- 定义一个中间变量
{% with total=business.employees.count %}
{{ total }} employee{{ total|pluralize }}
{% endwith %} - csrf_token
- 这个标签用于跨站请求伪造保护。
- 在页面的form表单里面写上{% csrf_token %}
- 用这个后就可以将中间件打开(这样就安全了,知道是我能够收取的)
- 在表单中添加了一个隐藏的input标签
- name csrfmiddlewaretoken
- value asksdasdas(64位)
- # 注释
- {# ... #} - 母版(一个普通的html文件) block extends
- 减少代码的重复 - 母版写好
- 不同的地方用以下占位
- {{ block contenter(name) }} {{ endblock }}
- 子文件
- {% extends '母版html' %} # 继承母版 - {% block contenter(name) %} # 将母版中的站好位置额contenter填充
自己的html文件
{% endblock %} - 注意事项:
- {% extends '母版html' %} # 继承母版 必须写在开头
- {% extends name %} name写继承的模板的名字字符串
- 自定义的内容写在block中
- 定义多个block块,一般要有js css - 注意事项
- Django的模板语言不支持连续判断,即不支持以下写法:
{% if a > b > c %}
...
{% endif %}
- Dja的模板语言中属性的优先级大于方法
def xx(request):
d = {"a": 1, "b": 2, "c": 3, "items": ""}
return render(request, "xx.html", {"data": d})
如上我们在使用render方法渲染一个页面的时候,传的字典d有一个key是items并且还有默认的 d.items()
方法,此时在模板语言中: {{ data.items }}
默认会取d的items key的值。 - 组件 include
- 可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方按如下语法导入即可。
{% include 'navbar.html' %} - 静态文件相关(动态拿取STATIC_URL配置的名字)
-
{% load static %}
<img src="{% static "images/hi.jpg" %}" alt="Hi!" /> 引用JS文件时使用:
{% load static %}
<script src="{% static "mytest.js" %}"></script> 某个文件多处被用到可以存为一个变量
{% load static %}
{% static "images/hi.jpg" as myphoto %}
<img src="{{ myphoto }}"></img> - get_static_prefix
{% load static %}
<img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!" /> 或者
{% load static %}
{% get_static_prefix as STATIC_PREFIX %} <img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi!" />
<img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!" /> - 自定义simpletag
和自定义filter类似,只不过接收更灵活的参数。 定义注册simple tag
@register.simple_tag @register.simple_tag(name="plus")
def plus(a, b, c):
return "{} + {} + {}".format(a, b, c) 使用自定义simple tag
{% load app01_demo %} {# simple tag #}
{% plus "" "" "abc" %} - inclusion_tag
- 多用于返回html代码片段 - 步骤
- 在app下创建templatetags的python包
- 在包下写py文件 mytags
- 编辑文件
- from django import template
- register = template.Library() - 定义函数
- 可接受参数
- 返回一个字典
- 函数加装饰器
- @register.inclusion_tag('result.html') 示例: templatetags/my_inclusion.py from django import template register = template.Library() @register.inclusion_tag('result.html')
def show_results(n):
n = 1 if n < 1 else int(n)
data = ["第{}项".format(i) for i in range(1, n+1)]
return {"data": data} templates/result.html <ul>
{% for choice in data %}
<li>{{ choice }}</li>
{% endfor %}
</ul> templates/index.html <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>inclusion_tag test</title>
</head>
<body> {% load my_inclusion %} {% show_results 10 %}
</body>
</html> - 细节
input data属性 value='是一个“-”链接的字符串'
Django总结一的更多相关文章
- 异步任务队列Celery在Django中的使用
前段时间在Django Web平台开发中,碰到一些请求执行的任务时间较长(几分钟),为了加快用户的响应时间,因此决定采用异步任务的方式在后台执行这些任务.在同事的指引下接触了Celery这个异步任务队 ...
- 《Django By Example》第四章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:祝大家新年快乐,这次带来<D ...
- django server之间通过remote user 相互调用
首先,场景是这样的:存在两个django web应用,并且两个应用存在一定的联系.某些情况下彼此需要获取对方的数据. 但是我们的应用肯经都会有对应的鉴权机制.不会让人家随随便便就访问的对吧.好比上车要 ...
- Mysql事务探索及其在Django中的实践(二)
继上一篇<Mysql事务探索及其在Django中的实践(一)>交代完问题的背景和Mysql事务基础后,这一篇主要想介绍一下事务在Django中的使用以及实际应用给我们带来的效率提升. 首先 ...
- Mysql事务探索及其在Django中的实践(一)
前言 很早就有想开始写博客的想法,一方面是对自己近期所学知识的一些总结.沉淀,方便以后对过去的知识进行梳理.追溯,一方面也希望能通过博客来认识更多相同技术圈的朋友.所幸近期通过了博客园的申请,那么今天 ...
- 《Django By Example》第三章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:第三章滚烫出炉,大家请不要吐槽文中 ...
- 《Django By Example》第二章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:翻译完第一章后,发现翻译第二章的速 ...
- 《Django By Example》第一章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:本人目前在杭州某家互联网公司工作, ...
- Django
一.Django 简介 Django 是一个由 Python 写成的开放源代码的 Web 应用框架.它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是 CMS(内容管理系统) ...
- Django admin定制化,User字段扩展[原创]
前言 参考上篇博文,我们利用了OneToOneField的方式使用了django自带的user,http://www.cnblogs.com/caseast/p/5909248.html , 但这么用 ...
随机推荐
- 入门系列(一) 微信小程序简介
一.简介 1.目录结构 首先,我们使用微信公众平台提供的开发者工具,创建一个简单的小程序项目,观察项目的目录结构 不难看出,一个典型的微信小程序,通常包含一个描述整体的主体部分,以及一个描述页面的 p ...
- Laravel学习:请求到响应的生命周期
Laravel请求到响应的整个执行过程,主要可以归纳为四个阶段,即程序启动准备阶段.请求实例化阶段.请求处理阶段.响应发送和程序终止阶段. 程序启动准备阶段 服务容器实例化 服务容器的实例化和基本注册 ...
- wannafly-day1 Problem B-Board
思路:这个题队友过的,我的思路是枚举行和列,将除了要求位置初始0,每行最小值相减,每列最小值相减,直到除了要求的位置,别的位置都为零,则那个位置取绝对值就行了,有点麻烦应该能过,但是他没有用我给的想法 ...
- [luoguP2863] [USACO06JAN]牛的舞会The Cow Prom(Tarjan)
传送门 有向图,找点数大于1的强连通分量个数 ——代码 #include <stack> #include <cstdio> #include <cstring> ...
- SCOI2010第一场
NOI2010全国青少年信息学奥林匹克竞赛 四川代表队选拔赛 第一场 题目名称 幸运数字 游戏 股票交易 英文代号 luckynumber game trade 时限 2秒 2秒 2秒 输入文件 lu ...
- pij——1125 Stockbroker Grapevine
Stockbroker Grapevine Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 37154 Accepted: ...
- Maven项目pom.xml报错
1.org.apache.maven.archiver.MavenArchiver.getManifest报错 pom.xml第一行报错,如图: 解决办法: 第一步: help ->Instal ...
- FreeMarker与Spring MVC 4结合错误:Caused by: java.lang.NoClassDefFoundError: org/springframework/ui/freemarker/FreeMarkerConfiguration
添加spring-context-support的依赖到POM: <!-- spring-context-support --> <!-- https://mvnrepository ...
- 安装elasticsearch遇到的签名和目标被配置多次的问题
命中:6 http://ppa.launchpad.net/ondrej/php/ubuntu bionic InRelease获取:7 http://packages.elastic.co/elas ...
- HDU 1973
Prime Path Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ...