记录学习Django的过程
System: MacOS 12.0 |
---|
Python: 3.8.9 |
Django: 2.2.1 |
初始
创建项目
使用PyCharm
新建Django项目
File/New Project/Django
如果没有提前安装Django则会自动安装最新版
命令行
创建项目命令
django-admin startproject 项目名
切换到项目目录
启动项目
python mange.py runserver
端口
默认端口为8000
修改端口号
PyCharm
编辑项目,修改Host:Port
命令行运行
python mange.py runserver ip:指定端口号
Index
一切就绪后通过访问127.0.0.1:8000
就能看到Django初始界面
Django目录结构
1 | |-- 项目名 |
Views.py
- 函数名称: 见名知意,遵循标识符规则。
- request参数: Django 将请求的所有的内容都封装到对象中,然后传递给视图函数的第一个参数。
- 返回值: 必须要有响应对象,可以是HttpResponse 也可以是子类。
1 | def index(request): |
Render函数
1 | # 导入函数 |
Urls.py
作用: 提供URL到视图函数之间的一个映射关系
URL先找到路由,然后路由再找到视图函数
1 | urlpatterns = [ |
HelloWorld
在项目包下创建一个views.py文件
1 | # 导入HttpResponse模块 |
修改urls.py文件
1 | # 从views导入hello函数 |
从浏览器访问127.0.0.1:8000/hello
即可看到HelloWorld
路由使用正则表达式
目的: 提高代码的复用率,减少代码冗余
urls.py
1 | # 格式 |
views.py
1 | # 使用正则匹配 |
Templates
在此文件夹下可以创建静态html文件
如果使用命令行创建项目,则需要手动创建此文件夹
且需要修改setting.py
1 | TEMPLATES = [ |
模板
页面显示数据
数据的替换是在内存中完成,然后将最终的替换完成的页面,返回给浏览器,浏览器再进行展示。
views.py
1
2
3
4
5
6
7
8
9def index2(request):
# 相当于从数据库中获取的数据
info_list = [
{'name': 'zs', 'age': 18},
{'name': 'lsi', 'age': 20},
{'name': 'wangw', 'age': 22},
]
# 第三个值:类型是字典。key 任意,value 为要在页面上显示的值
return render(request, 'index2.html', {'info_list': info_list})urls.py
添加路由
1
2
3...
path('index2/', views.index2),
...index2.html
1
2
3
4
5...
<body>
{{ info_list }}
</body>
...locals()函数
它返回对所有局部变量的名称与值进行映射,即包括所有的局部变量,不用再重新定义一遍临时变量
故,可以将上面views.py结尾处
{'info_list': info_list}
改为locals()
页面显示不同类型的数据
列表数据
views.py
1
2
3
4def index3(request):
# 返回列表
hero_list = ['枣庄王', '石家庄赵子龙', '包头吕布', '小鲁班']
return render(request, 'index3.html', locals())urls.py
1
2
3...
path('index3/', views.index3),
...index3.html
1
2
3
4
5
6
7
8
9...
<body>
{{ hero_list }}
{# 获取列表中的数据,方法:变量名称.索引 #}
<br>
{{ hero_list.1}}
{# 石家庄赵子龙 #}
</body>
...
字典数据
views.py
1
2
3def index4(request): # 字典
user_info = {'name': '尼古拉斯-赵四', 'age': 40, 'gender': '男'}
return render(request, 'index4.html', locals())urls.py
1
2
3...
path('index4/', views.index4),
...index4.html
1
2
3
4
5
6
7
8...
<body>
{{ user_info }}
{# 获取字典中的value,方法:变量名称.key #}
<br>
用户名是:{{ user_info.name }},今年:{{ user_info.age }}岁,性别为:{{ user_info.gender }}
</body>
...
组合数据类型
views.py
1
2
3
4
5
6
7
8
9
10def index4(request): # 字典
user_info = {'name': '尼古拉斯-赵四', 'age': 40, 'gender': '男'}
# 组合型
user_info_list = [
{'name': '赵四', 'age': 40, 'gender': '男'}, {'name': '刘能', 'age': 30, 'gender': '男'}, {'name': '宋小宝', 'age': 20,
'gender': '男'}
]
person_info = {'name': '于谦', 'age': 29, 'hobby': ['抽烟', '喝酒', '烫头']}
return render(request, 'index4.html', locals())index4.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22<body>
{{ user_info }}
{# 获取字典中的数据,方法:变量名称.key #}
<br>
用户名是:{{ user_info.name }},今年:{{ user_info.age }}岁,性别为:{{ user_info.gender }}
<hr>
<p>
{# 获取列表中字典中的值 #}
{{ user_info_list }}
<hr>
索引为1的字典中key为name的名字是:{{ user_info_list.1.name }}
<br>
索引为0的字典中key为name的名字是:{{ user_info_list.0.name }}
</p>
<hr>
<p>
{# 获取字典中列表中的值 #}
{{ person_info }}
<br/>
字典中的列表索引为2的爱好是:{{ person_info.hobby.2 }}
</p>
</body>
对象数据
views.py
1
2
3
4
5
6
7
8class Dog():
def __init__(self, name):
self.name = name
pass
def eat(self):
return '爱吃骨头'
passdef index5(request):
# 创建对象 dog_obj = Dog('大黄') return render(request, 'index5.html', locals())
1 | - urls.py |
…
path(‘index5/‘, views.index5),
…
1 | - index5.html |
标签(Tags)
作用: 可以做一些简单的业务逻辑。
格式: {% 标签名称 %} {% end标签名称 %}
单分支
views.py
1
2
3def tag(request):
age = 16
return render(request, 'tag.html', locals())urls.py
1
2
3...
path('tag/', views.tag),
...tag.html
1
2
3
4
5
6
7
8
9
10
11
12...
<body>
{# 单分支 #}
{% if age < 18 %}
如果年龄小于18岁,则输出如下内容:
<br>
<h2>
好好学习,天天向上
</h2>
{% endif %}
</body>
...
双分支
tag.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19...
<body>
...
{# 双分支 #}
{% if age < 16 %}
如果年龄小于16岁,则输出如下内容:
<br>
<h2>
好好学习,天天向上
</h2>
{% else %}
如果年龄大于16岁,则输出如下内容:
<br>
<h2>
欢迎来到成年人的世界
</h2>
{% endif %}
</body>
...
多分支
tag.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15...
<body>
...
{# 多分支 #}
{% if age > 0 and age < 18 %}
<h2>我是祖国的花朵...</h2>
{% elif age >= 18 and age <= 30 %}
<h2>我是小鲜肉...</h2>
{% elif age > 30 and age <= 50 %}
<h2>我是老腊肉...</h2>
{% else %}
<h2>我是....</h2>
{% endif %}
</body>
...
ifequal
tag.html
1
2
3
4
5
6
7
8
9
10
11...
<body>
...
{# ifequal #}
如果变量值和常量相同则执行if体,否则不执行。<br>
{% ifequal age 16 %}
如果年龄为16则输出如下内容:<br>
<h2>my age is {{ age }}...</h2>
{% endifequal %}
</body>
...
for
格式:
1 | {% for hero in hero_list%} |
forloop
1 | ... |
for…empty
如果变量有值则执行循环,如果变量没有值,则执行 empty 中对应的内容。
views.py
1
2
3
4
5def index4(request):
...
null_list = []
...
...index4.html
1
2
3
4
5
6
7
8
9
10<body>
...
{% for nothing in null_list %}
{{ nothing }} <br/>
{% empty %}
购物车空空的哦~,去看看心仪的商品吧~
<a href="https://www.jd.com">去购物 ></a>
{% endfor %}
...
</body>
static
需要在项目根目录自行创建
且需要修改setting.py
1 | STATIC_URL = '/static/' |
html
1
2
3<br>
图片展示
<img src="../static/wallpaper.jpg" width="546" height="364"/>
load static
1 | {% load static %} |
效果同上
继承
提高代码的重用率
创建父页面
base.html
1
2
3
4
5
6
7
8
9
10
11
12
13...
<body>
{# 相同的代码抽取出来,放到父页面中 #}
<h1 style="background-color: orangered ; height: 50px; line-height: 2px; "></h1>
{% block main %}
{# 子页面不同的地方,通过block标签进行,预留位 #}
{% endblock %}
<h1 style="background-color: orangered ; height: 50px; line-height: 2px; "></h1>
</body>
...创建子页面
index.html
1
2
3
4
5
6
7{% extends 'base.html' %}
<h1>
继承父类
</h1>
{% block main %}
<h1>不使用父类代码</h1>
{% endblock %}创建父页面
base.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18...
<title>
{% block title %}
{% endblock %}
</title>
</head>
<body>
<h1 style="...">
header
</h1>
{% block main %}
{% endblock %}
<h1 style="...">
footer
</h1>
</body>
...创建子页面
index.html
1
2
3
4
5
6
7
8{% block main %}
<h1>
index...
</h1>
{% endblock %}
{% block title %}
首页
{% endblock %}可见使用了{% block main %}的h1标签正常显示了,而{% block title %}因为父页面中为空所以不显示
include
提高代码的复用率
当页面代码相同部分较少,且内容不变,例如每个页面的footer部分
views.py
1
2
3
4...
def home(request):
return render(request, 'home.html', locals())
...urls.py
1
2
3...
path('home/', views.home),
...创建
home.html
1
2
3
4
5
6
7
8...
<body>
<h1>
我是home
</h1>
{% include 'footer.html' %}
</body>
...创建
footer.html
1
2
3
4
5
6
7...
<body>
<h1>
我是footer
</h1>
</body>
...
过滤器(Filters)
作用: 可以在变量被显示前修改它,过滤器使用管道字符
过滤器本质: 就是函数
格式: `{{ 数据|过滤器:可选参数 }}`
- {{ 数据 |upper }}
将数据变成大写
1
2# 假设name的值为zhangsan
经过过滤器{{ name|upper}}输出结果为ZHANGSAN - {{ 数据|lower}}
将数据变成小写
1
2# 假设name的值为ZHANGSAN
经过过滤器{{ name|lower}}输出结果为zhangsan - {{ 数据|lower|upper}}
先将数据变成小写再变成大写
1
2# 假设name的值为ZhangSan
经过过滤器{{ name|lower|upper}}输出结果为ZHANGSAN addslashes:添加反斜杠到任何反斜杠、单引号或者双引号前面
date:按指定的格式字符串参数格式化 date 或者 datetime 对象
length:返回变量的长度
default:当变量为空或False时提供默认值
filesizeformat:以格式显示文件大小,字典返回的是键值对的数量,集合返回的是去重后的长度
date:根据给定格式对一个日期变量进行格式化
truncatechars:如果字符串包含的字符总个数多于指定的字符数量,那么会被截断掉后面的部分。截断的字符串将以 … 结尾。
safe:将字符串标记为安全,不需要转义。
1 | ... |