一、Django基础–views视图函数
“这是我参与更文挑战的第2天,活动详情查看: 更文挑战”
视图 CBV和FBV
FBV
function based view ,平常用函数写的就是FBV
CBV
class based view ,用面试对象的方式就是CBV
from django.views import View
class xxx(View):
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)#其实
def get(self,request):
#专门处理get请求
return response
def post(self,request):
#专门处理post请求
return response
url(r"xx/",xxx.as_view()) # 类名.as_view()执行
as_view()的流程
1. 项目运行时加载urls.py文件,执行类,as_view()方法
2. as_view()执行后,内部定义了一个view函数,并且返回.
3. 请求到来的时候,执行view函数
1. 实例化类--> self
2. self.request = request
3. 执行self.dispath(request,*args,**kwargs)方法
1. 判断请求方式是否被允许
1. 允许: - 通过反射获取请求方式对应的请求方法--->handler f.html_method_not_allowed -->handler
2. 不允许:- self.http_method_not_allowed -->handler
2. 执行hanlder,返回结果
# http_method_names = ['get'] #只允许提交的请求方法,内部执行View这个函数的时候,就会先访问这个类,这个http_method_names就会覆盖内部的这个方法
def dispatch(self, request, *args, **kwargs):
print("dispatch执行前的操作")
ret = super().dispatch(request, *args, **kwargs)#其实就是执行View里面内部的dispatch方法
print("dispatch执行后的操作")
return ret
CBV执行get和post方法前会,先执行dispatch方法
使用过程CBV
1. 写url url(r"^books/$", views.books.as_view()),
2. 在视图函数写方法
# url.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r"^books/$", views.books.as_view()),
]
# views.py
from django.views import View
class books(View):
def dispatch(self, request, *args, **kwargs):
print("1")
func = super().dispatch(request, *args, **kwargs)
print("2")
return func
def get(self, request):
# 专门处理get请求
return render(request, "login.html")
def post(self, request):
# 专门处理post请求
user = request.POST.get("user")
password = request.POST.get("password")
user_obj = models.User.objects.filter(username=user, password=password)
if not user_obj:
return render(request, "login.html")
return render(request, "index.html")
FBV,CBV加装饰器
FBV加装饰器
直接加在函数上就行了
CBV加装饰器
需要使用一个装饰器,导入包method_decorator
from django.utils.decorators import method_decorator
@method_decorator 是将函数装饰器转换成方法装饰器。
加在方法上
@method_decorator(timer)
def get(self, request): #这样就只能get方法可以用
@method_decorator(timer) #里面的定义的请求方法都可以用
def dispatch(self, request, *args, **kwargs):
print(“dispatch执行前的操作”)
ret = super().dispatch(request, *args, **kwargs)#其实就是执行View里面内部的dispatch方法
print(“dispatch执行后的操作”)
return ret
@method_decorator(timer,name=“get”)
@method_decorator(timer,name=“post”)
@method_decorator(timer,name=“dispatch”)
class PublishersAdd(View): #加在类上,可以指定对应的方法
装饰器:timer
# 统计时间的装饰器
import time
from functools import wraps
def timer(func):
@wraps(func)
def inner(*args, **kwargs):
"""
inner内部函数
"""
start = time.time()
ret = func(*args, **kwargs)
print("执行一共用时:{}".format(time.time() - start))
return ret
return inner
@timer
def func():
"""
我是func函数
"""
time.sleep(0.5)
print("aaaa")
func()
print(func.__name__) #打印函数名 inner (只有加 @wraps(func),才可以输出func,自己的函数名)
print(func.__doc__) #打印函数中的注释
from functools import wraps
@wraps(func) #加wraps才可以输出自己的函数,和注释,不然会输出内部函数里面
request(请求)
常用属性:
request.method 请求方法 GET POST
request.GET URL上携带的参数 ?k1=v1$k2=v2 {}
request.POST post请求提交的数据 {} 编码方法是URLencode
request.path_info 路径信息 不包含IP和端口 也不包含参数 /publisher_list/
request.body 请求体,byte类型 request.POST的数据就是从body里面提取到的(获取的是post请求提交的内容)
request.COOKIES cookies
request.session session类似于字典的对象
request.FILES 上传的文件
request.META 头的信息 小写-->大写 HTTP_开头
不常用属性:
request.scheme() http或https
request.path() 表示请求的路径组件(不含域名)
常用方法:
request.get_full_path() 完整的路径信息 不包含IP和端口 ,包含参数
request.is_ajax() 请求是否是ajax请求
response(响应)
from django.shortcuts import render, HttpResponse, redirect
HttpResponse("字符串") #返回字符串
render(request,"模板的文件名",{'k1':v1}) #返回一个HTML页面
redirect('地址') #重定向 其实就是给了 Location '地址'和状态码 301 302
from django.http import JsonResponse
def text_json(request):
a = {"a":"b"}
b = ["aa","bb"]
return JsonResponse(b,safe=False) #加safe=False了可以传递列表
二、Django基础–模板语法
模板常用语法
return render(request,“模板的文件名”,{“k1”:“xxx”}) #返回一个HTML页面
Django模板中只需要记两种特殊符号:
1.1 { { }}和 {% %}
1.2 { { }}表示变量,在模板渲染的时候替换成值,{% %}表示逻辑相关的操作。
点(.)在模板语言中有特殊的含义,用来获取对象的相应属性值
数字:{ { num }}
字符串:{ { string }}
字典:{ { name_dict }} --> { { name_dict.keys }} --> { { name_dict.values }} --> { { name_dict.name }}
列表:{ { name_list }} --> { { name_list.2 }}
集合:{ { set }} --> { { set.1 }}
元组:{ { tup }} --> { { tup.0 }}
类:{ { person }} --> { { person.name }} --> { { person.talk }}
.
.索引 .key .属性 .方法(方法后面不加括号)
优先级:
.key > .属性 .方法 > .索引
过滤器
过滤器的语法: { { value|filter_name:参数 }}
使用管道符"|"来应用过滤器。
过滤器:Filters
return render(request,“template_text.html”,{“new_num”:""})
{ {变量|过滤器:“参数”}}
default:
变量不存在或者为空时使用默认值 ,如果value值没传的话就显示nothing
{ { new_num|default:“2” }}
filesizeformat
return render(request, “template_text.html”, {“value”: 1024 * 1024 * 1024})
{ { value|filesizeformat }} # filesizefomrat:1.0 GB
add +
给变量加参数
数字的加法,字符串和列表的拼接
add:{ { value2|add:“2” }} --> 列表相加:{ { name_list|add:name_list }} #add:4 --> 列表相加:[‘张三’, ‘李四’, ‘王五’, ‘张三’, ‘李四’, ‘王五’]
lower,upper,title
小写:{ {value|lower}}
大写:{ {value|upper}}
标题:{ {value|title}} #首字母大写
可以写在一起:{ {value|upper|lower|title}}
length
{ { value|length }}
返回value的长度,如 value=[‘a’, ‘b’, ‘c’, ‘d’]的话,就显示4.
slice 切片
{ { name_list|slice:“0:2” }} #和python一样就是没有[]号 [0:2]
first,last
{ {value:first}} #取第一个元素 和 { {value.0}}一样
{ {value:last}} #取最后一个元素
join 字符串拼接
使用字符串拼接列表。同python的str.join(list)。
{ { value|join:" __ " }} #张三__李四__王五
truncatechars 字符串截取
如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“…”)结尾。
参数:截断的字符数
{ { long_str|truncatechars:9 }} #包括3个省略号 Django…
truncatewords :根据单词截断
date 日期格式化
import datetime
now = datetime.datetime.now()
{ { now|date:“Y-m-d H:i:s” }}2020-08-08 10:17:14
或者直接在settings.py里面定义格式
1. USE_L10N = False
2. 设置格式:
DATETIME_FORMAT = ‘Y-m-d H:i:s’
TIME_FORMAT = ‘H:i:s’
DATE_FORMAT = ‘Y-m-d
然后直接:{
{ now }},就和上面一样的
safe
Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全
比如:
“safe_text”:“点我”,
{ { safe_text}}
我们就会在页面上获得字符串:点我
有时候我们不想这样,我们就可以加个safe
{ {safe_text|safe}} # 点我
mark_safe
from django.utils.safestring import mark_safe
@register.filter
def show_b(name,url):
return mark_safe('{}'.format(url,name)) #直接这样写就不用在用的时候加safe了
{ { ‘百度’|show_b:“http://www.baidu.com” }}
自定义过滤器 filter
在app下创建一个名为templatetags的python包(包的名字不能错,必须叫templatetags)
创建一个python文件,文件名自定义(mytags.py)
创建自定义过滤器:
from django import template
register = template.Library() # register的名字不能错
@register.filter
def add_arg(value, arg): #只能写二个参数,一个是变量,一个是过滤器的参数
# 功能
return "{}__{}".format(value, arg)
母版和继承
母版:
1. 一个包含多个页面的公共部分
2. 定义多个block块,让子页面进行覆盖
复制代码
继承:
1. {% extends "母版的名字" %} # xx.html
{# 留着模板的内容#}
{
{ block.super }}
复制代码
2. 重新复写block块 (就是覆盖了母版的block块)
复制代码
注意点:
例
创建母版:
{% load static %}
母版
{% block css %} {% endblock %} {# css#}
{% block content %} {# 内容#} {% endblock %}
{% block js %} {# js#} {% endblock %}
使用母版:
{% extends "Master.html" %}
{% block css %}
{% endblock %}
{% block content %}
123321
{% endblock %}
{% block js %}
{% endblock %}
组件 include
可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方,文件的任意位置按如下语法导入即可。
复制代码
示例
创建组件
组件
- 1
- 2
- 3
- 4
- 5
使用组件
{% extends "Master.html" %}
{% block css %}
{% endblock %}
{% block content %}
{% include "nav.html" %}
123321
{% endblock %}
{% block js %}
{% endblock %}
标签tags
for
for循环可用的一些参数:
Variable Description
forloop.counter 当前循环的索引值(从1开始)
forloop.counter0 当前循环的索引值(从0开始)
forloop.revcounter 当前循环的倒序索引值(到1结束)
forloop.revcounter0 当前循环的倒序索引值(到0结束)
forloop.first 当前循环是不是第一次循环(布尔值)
forloop.last 当前循环是不是最后一次循环(布尔值)
forloop.parentloop 本层循环的外层循环
for …empty
{% for name in name_list2 %}
{
{ name }}
{% empty %}
为空了 #如果循环的对象为空的话,就输出它
{% endfor %}
if
{% if value2 > 2 %}
可以
{% elif value2 == 2 %}
不错
{% endif %}
if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。
注意:
with
就是重命名
{% with name_list as name%}
{
{ name }}
{
{ name }}
{% endwith %}
或者
{% with name = name_list %}
{
{ name }}
{
{ name }}
{% endwith %}
自定义标签 simple_tag
app应用文文件夹中创建templatetags文件夹,必须是这个名字;
templatetags文件夹中创建一个xx.py文件,名字可以随便起。
创建自定义标签
from django import template
register = template.Library() # register固定的名字
@register.simple_tag
def mytag(v1):
s = v1 + '我爱你'
return s
@register.simple_tag
def mytag2(v1, v2, v3):
s = v1 + v2 + v3
return s
使用 html文件中的 {% load 文件名 %} {% load te %} {% mytag s1 %} {% mytag2 s1 ‘yyz’ ‘lt’ %}
注意:参数可以有多个。
inclusion_tag
filter, simple_tag,inclusion_tag
没有参数限制的
写函数+加装饰器
filter:
def add_arg(value,arg): #只能接受一个参数和值
return “xx”
simple_tag:
@register.simple_tag # 可以接受多个参数和值
def str_join(args, kwargs):
return “{}_{}”.format("—".join(args), "".join(kwargs))
inclusion_tag:
@register.inclusion_tag(“page.html”) #把值返回到page.html页面上
def pagination(num):
return {‘num’: range(1, num + 1)} # 需要返回的是一个字典
使用
filter:
{% load mytags %}
{% “alex”| add_arg:“我爱你” %}
simple_tag:
{% load mytags %}
{% str_join “a” “b” “c” k1=“aa” k2=“bb” %}
{#a—b---c_k1***k2#}
inclusion_tag:
{% load mytags %}
{% pagination 6 %}
实例(分页)
from django import template
from django.utils.safestring import mark_safe
register = template.Library()
# 方法一
@register.simple_tag
def pagination(num):
page_list = ['{} '.format(i) for i in range(1,num+1)]
print(page_list)
return mark_safe("""
""".format(''.join(page_list)))
# 方法二:
@register.inclusion_tag("page.html")
def pagination(num):
return {'num': range(1, num + 1)} # 需要返回的是一个字典