1. 建立虚拟环境

虚拟环境是系统的一个位置,可以在其中安装包,并将其与其他Python包隔离。将项目的库与其他项目分离是有益的,且为了后续将项目部署到服务器,这也是必须的。

1
$ python -m venv ll_env

运行了模块venv,并使用它来创建一个名为ll_env的虚拟环境。
建立虚拟环境后,需要使用下面的命令激活它:

1
$ ll_env\Scripts\activate

这个命令运行ll_env/bin中的脚本activate。环境处于活动状态时,环境名将包含在括号内。在这种情况下,你可以在环境中安装包,并使用已安装的包。你在ll_env中安装的包仅在该环境处于活动状态时才可用。

要停止使用虚拟环境,可执行命令deactivate:

1
2
(ll_env)learning_log$ deactivate
learning_log$

或关闭运行虚拟环境的终端,虚拟环境也将不再处于活动状态。

创建并激活虚拟环境后,就可安装Django了:

1
(ll_env)learning_log$ pip install Django

2. Django中创建项目

创建一个名为mysite的项目:

1
django-admin startproject mysite

manage.py的文件接受命令并将其交给Django的相关部分去运行。我们将使用这些命令来管理诸如使用数据库和运行服务器等任务。python manage.py xxx

文件 settings.py是配置文件。文件urls.py是路由系统。文件wsgi.pyweb server gateway interface(Web服务器网关接口)的缩写,用于定义Django用的socket。

初始运行:(默认8000端口)

1
python manage.py runserver (127.0.0.1:8080)

3. 配置

路径配置:

屏幕截图 2021-01-19 183209.jpg

由于新增了templates目录存放模板,static_file目录存放静态文件(照片、css、js文件),需要对settings.py作如下配置:

屏幕截图 2021-01-19 183433.jpg

1
2
3
4
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static_file'), # 注意逗号
)

注释掉:(这一句是为防止跨站请求伪造,注释掉方便在多url之间跳转查看)

1
'django.middleware.csrf.CsrfViewMiddleware',

csrf通过生成随机字符串来防止跨站请求伪造,若不注释掉,需要:

1
2
3
<form method="POST" action="..."> 
{% csrf_token %}
</form>

来通过验证。若要局部禁用,让某些函数无需csrf验证,可以:

1
2
3
4
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def fun():
pass

局部使用,即csrf语句已经注释掉,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from django.views.decorators.csrf import csrf_protect
@csrf_protect
def fun():
pass

# 对于 CBV:
from django.utils.decorators import method_decorator
from django.views import View
@method_decorator(csrf_protect, name='dispatch')
class Foo(View):
def get():
pass
def post():
pass

BASE_DIR是当前基本路径。由于Django是根据路由寻找,而非根据路径寻找啊,因此在html中引入css文件时,应当引入的是其路由:

1
2
3
4
5
<head lang="en">
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="/static/common.css"/>
</head>

路由:

访问 http://127.0.0.1:8000/login/

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
###  urls.py  ###
from django.shortcuts import HttpResponse, render, redirect
def login(request):
'''
requset: 用户请求相关的所有信息(对象)
'''
# return HttpResponse('login') # HttpResponse无需自己处理信息
if request.method == "GET":
return render(request, 'login.html') # 自动找到模板文件下的目标文件,读取内容(需要在settings.py中配置路径)
else:
user = request.POST.get('username')
password = request.POST.get('password')
if user=='dhy' and password=='123':
return redirect('/index/')
else:
return render(request, 'login.html', {'msg':"ERROR"})

def index(request):
return HttpResponse("index")

urlpatterns = [
# path('admin/', admin.site.urls),
path('login/', login),
path('index/', index),
]

url还可以用正则匹配:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from django.urls import re_path
urlpatterns = [
re_path('index/(\w+)/(\w+)/.html', views.index),
# 加.html -> 伪静态
re_path('edit/(?P<a2>\w+)/(?P<a1>\w+)/', views.edit),
re_path('', default),
]
def index(request, a1, a2):
# 对于第一种方式必须按顺序接受group分组结果
pass
def edit(request, a1, a2):
# 第二种指定参数名,无需按照顺序
pass
def default(request):
# 对于不在urlpatterns中的url指定一个默认返回页面
return HttpResponse("无人...")

反向生成url:

1
2
3
4
5
6
7
8
9
# 给url指定一个别名 n1
re_path('index/(?P<addition>\w+)/', views.index,name="n1"), # 1
re_path('index/(\w+)/', views.index,name="n1"), # 2

# 可以根据别名找到url
from django.urls import reverse
def index(request, addition):
v = reverse('n1',kwargs={'addition':'aa'}) # 1. /index/aa/
v = reverse('n1',args=('aa',)) # 2. /index/aa/
  • 请求相关信息

    • request.method:获取请求方式
    • request.GET:获取请求头中urlGET请求传递的信息
    • request.POST:获取请求体信息(POST方式传递的数据)
  • 传递信息

    • return HttpResponse("...")
    • return render(request, ‘模板路径’,{}):返回模板,参数为请求+模板名+模板渲染所需参数
    • return redirect("URL"):重定向,可以是路由也可以是要跳转的网址

视图:

有CBV(class basic views)和FBV(function basic views)

  1. CBV模式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# -- urls.py -- #
from manageapp1 import views
urlpatterns = [
path('login.html', views.Login.as_view()),
]

# -- views.py -- #
from django.views import View
class Login(View):
'''
get -> 查
post -> 创建
put -> 更新
delete -> 删除
'''
def get(self, request):
# get请求会匹配到这个函数
pass
def post(self, request):
# POST请求会匹配到这个函数
return HttpResponse("POST")

​ 对于每个class,都是先执行dispatch方法,通过dispatch里的getattr()寻找函数,执行完毕后通过dispatch返回。因此可以通过修改dispatch函数来实现装饰器效果。

1
2
3
4
5
6
7
class Login(View):

def dispatch(self, request, *args, **kwargs):
print("before")
obj = super(Login, self).dispatch(request, *args, **kwargs)
print("after")
return obj

4. 模板引擎中的标记

1. 基础

1
2
3
4
5
6
7
8
9
10
11
12
<!-- 变量 -->
{{ name }}
<!-- 循环 -->
{% for row in list %}
<!-- row是列表,访问0号元素 -->
{row.0}
<!-- row是字典,访问key对应的内容 -->
{row.key}
{% endfor %}

<!-- 如果/index/有name=xx, 可以用于生成url,ij填充的是正则部分 -->
{% url "xx" i j %}

2. 母板继承

Django中可以使用模板继承。被继承的是母板。子板可以在母板设置的block中填充内容,并继承其他共同部分。

在母板中,一般至少有三个block:

1
2
3
4
5
6
{% block css %}
{% endblock %}
{% block content %}
{% endblock %}
{% block js %}
{% endblock %}

子板继承:

1
2
3
4
{% extends "layout.html" %}
{% block content %}
...
{% endblock %}

3. 函数

.函数名即可执行函数

  • 遍历字典:
1
2
3
{% for k,v in dict.items %}
{k} - {v}
{% endfor %}
  • 字母大写
1
{{name|upper}}

自定义函数:

  1. 在app中创建templatetags模块

  2. 创建任意 .py 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
from django import template
from django.utils.safestring import mark_safe

register = template.Library() # register名称不可变

@register.simple_tag
def my_simple_time(v1,v2,v3):
return v1 + v2 + v3

@register.simple_tag
def my_input(id,arg):
result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
return mark_safe(result)
  1. 在使用自定义simple_tag的html文件中导入之前创建的 xx.py 文件名
1
{% load xx %}
  1. 使用simple_tag
1
2
{% my_simple_time 1 2 3%}
{% my_input 'id_username' 'hide'%}
  1. 在settings中配置当前app,不然django无法找到自定义的simple_tag
1
2
3
4
INSTALLED_APPS = (
...
'app01',
)