day48 Django视图函数,模板渲染和静态文件配置
视图函数
request对象
request.path #request.path当前请求路径
request.method #当前请求方法(get,post...)
request.GET # 获取所有get请求携带过来的数据
request.POST # 获取所有post请求携带过来的数据
request.body # 获取所有post请求携带过来的数据的原始格式
response对象
render 回复html页面
redirect 重定向
HttpResponse 回复字符串
CBV和FBV
- FBV,function based view:基于函数的视图逻辑
- CBV,class based view:基于类的视图逻辑
CBV中url写法
# url(r'^login/', views.login),
url(r'^login/', views.LoginView.as_view()),
视图写法
from django.views import View
class LoginView(View):
def get(self,request):
return render(request, 'login.html')
def post(self,request):
uname = request.POST.get('username')
pwd = request.POST.get('password')
if uname == 'alex' and pwd == 'dsb':
return redirect('/home/')
else:
return redirect('/login/')
源码重点
def dispatch(self, request, *args, **kwargs): #根据请求方法去分发对应的类发放来执行
# Try to dispatch to the right method; if a method doesn't exist,
# defer to the error handler. Also defer to the error handler if the
# request method isn't on the approved list.
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed) #反射!!!!
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
重写dispatch方法
class LoginView(View):
def dispatch(self, request, *args, **kwargs):
print(11111)
# print(request.META) #http所有相关请求头信息
ret = super().dispatch(request, *args, **kwargs) #render(request, 'login.html')
print(2222)
return ret
def get(self,request):
print('this is get method!!!')
return render(request, 'login.html')
def post(self,request):
uname = request.POST.get('username')
pwd = request.POST.get('password')
if uname == 'alex' and pwd == 'dsb':
return redirect('/home/')
else:
return redirect('/login/')
CBV和FBV的装饰器
def func(f):
def foo(request):
print(1111)
ret = f(request)
print(2222)
return ret
return foo
# FBV模式下,和普通函数加装饰器是一样的写法
@func
def home(request):
print('home')
return HttpResponse('你好,老了老弟,进来玩会!')
# CBV加装饰的三个姿势:
from django.utils.decorators import method_decorator
# @method_decorator(func,name='get') 位置3
class LoginView(View):
# @method_decorator(func) #位置2
def dispatch(self, request, *args, **kwargs):
print('aaaa')
ret = super().dispatch(request, *args, **kwargs) #render(request, 'login.html')
print('bbbb')
return ret
@method_decorator(func) #位置1
def get(self,request):
print('this is get method!!!')
return render(request, 'login.html')
def post(self,request):
uname = request.POST.get('username')
pwd = request.POST.get('password')
if uname == 'alex' and pwd == 'dsb':
return redirect('/home/')
else:
return redirect('/login/')
模板渲染
settings配置
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')] #别忘了配置这个路径
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
模板语法
{{ 变量 }} {% 逻辑 %}
万能的句点号.
<h1>{{ num }}</h1>
<h1>{{ s }}</h1>
<h1>{{ l1.1 }}</h1>
<h1>{{ d1.number }}</h1>
<h1>{{ a.yue }}</h1> #注意,调用方法时,不能加括号,所有如果方法带参数,就没法用了
<h1>{{ a.xx }}</h1>
views.py
的写法
def home(request):
num = 100
s = 'hello my girl I love you'
l1 = [11,22,33]
d1 = {'name':'冠希哥','number':1000}
class A:
balance = 2000
def __init__(self):
self.xx = 'oo'
def yue(self):
return 'how much!'
a = A()
# render({'xx':'oo'})
return render(request,'home.html',{'num':num,'s':s,'l1':l1,'d1':d1,'a':a})
过滤器
过滤器用法 {{ 变量|过滤器名称:'参数' }}
,不是所有过滤器都有参数,如果没参数的话写法:{ 变量|过滤器名称 }}
内置过滤器
<h1>{{ s|truncatechars:n }}</h1> # 过滤器里面的参数都可以写后端返回的变量
default -- <h1>{{ xx|default:'抱歉,没有数据!!' }}</h1> # 默认值
length -- <h1>{{ l1|length }}</h1> # 获取变量数据长度
filesizeformat -- <h2>{{ file_size|filesizeformat }}</h2> # 大小按照人类可读的显示
slice -- <h2>{{ s|slice:'0:7' }}</h2> #切片 顾头不顾腚
date: -- <h3>{{ now|date:'Y-m-d H:i:s' }}</h3> # 日期格式化显示
safe -- <h1>{{ a_tag|safe }}</h1> 数据: a_tag = "<a href='http://www.baidu.com'>百度</a>"
truncatechars -- <h1>{{ s|truncatechars:'6' }}</h1>
join -- <h1>{{ l1|join:'+' }}</h1>
safe介绍
Django的模板中在进行模板渲染的时候会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全,django担心这是用户添加的数据,比如如果有人给你评论的时候写了一段js代码,这个评论一提交,js代码就执行啦,这样你是不是可以搞一些坏事儿了,写个弹窗的死循环,那浏览器还能用吗,是不是会一直弹窗啊,这叫做xss攻击,所以浏览器不让你这么搞,给你转义了。但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。
补充内容
url斜杠
url(r'^home/', views.home), #前置导航斜杠不需要写,后面的斜杠是根据django的配置来的,如果在settings配置文件中我们设置了
# APPEND_SLASH = False,那么浏览器发送来的请求如果没有带着后面的斜杠,也是可以正常请求的,但是如果没有这个配置的话,django要求浏览器必须带着路径后面的斜杠来进行访问,如果你输入路径的时候没有加/,那么django让你的浏览器发一个重定向请求带上/.
静态文件配置
在项目中,js
、css
、jgp图片
等等都称为静态文件
在django
中的使用
- 配置,在
settings
配置文件中写上以下配置
STATIC_URL = '/static/' #127.0.0.1:8000/static/bootstrap/css.
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'jingtaiwenjianjia'),
]
html
文件中使用
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
相对路径引入静态文件时,前置斜杠必须加上,不管是什么,a标签也是一样,相对路径访问必须前面的斜杠