Django 名称空间、伪静态、视图层、FBV与CBV介绍
名称空间
- 当多个应用出现了相同的别名 正常情况下的反向解析是没有办法自动识别前缀的
解决方法:
1. 名称空间
# 总路由
url(r'^app01/',include('app01.urls',namespace='app01')),
url(r'^app02/',include('app02.urls',namespace='app02'))
# 解析的时候
app01:
urlpatterns = [
url(r'^reg/',views.reg,name='reg')
]
app02:
urlpatterns = [
url(r'^reg/',views.reg,name='reg')
]
reverse('app01:reg')
reverse('app02:reg')
前端:
{% url 'app01:reg' %}
{% url 'app02:reg' %}
# 但只要保证名字不冲突 就没有必要使用名称空间
2. 有多个app的时候,起别名的时候加上app的前缀,这样的话就能保证多个app之间名字不冲突
app01:
urlpatterns = [
url(r'^reg/',views.reg,name='app01_reg')
]
app02:
urlpatterns = [
url(r'^reg/',views.reg,name='app02_reg')
]
伪静态
伪静态指的是将一个动态网页伪装成静态网页
静态网页: 数据写死了的 以后都不会边的网页
伪静态的作用:
- 伪静态的目的在于增大本网站的seo查询力度并且增加搜索引擎收藏本网站的概率
总结:
- 无论怎么优化 怎么处理 都是干不过RMB玩家
视图层
三板斧
"""
HttpResponse
返回字符串类型
render
返回html页面 并且在返回给浏览器之前还可以给html文件传值
redirect
重定向
"""
注意: 视图函数必须要返回一个HttpResponse对象 通过查看源码可知,render和redirect都继承了 HttpResponse
render 简单内部原理:
def myrender(request):
from django.template import Template,Context
res = Template('<h1>{{ user }}</h1>')
con = Context({'user':{'username':'jason','password':123}})
ret = res.render(con)
print(ret)
return HttpResponse(ret)
JsonResponse对象
'''
json格式数据,能够实现前后端跨语言传输数据
前端序列化
JSON.stringify() 对应 json.dumps()
JSON.prase() 对应 json.loads()
'''
给前端返回字符串
import json
from django.http import JsonResponse
def ab_json(request):
user_dict = {'username':'jason好帅哦,我好喜欢!','password':'123','hobby':'girl'}
l = [111,222,333,444,555]
# 1. 方式1
# 先转成json格式字符串
json_str = json.dumps(user_dict,ensure_ascii=False)
# 将该字符串返回
return HttpResponse(json_str)
# 2. 方式2
# 读源码掌握用法
return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})
注意:
# JsonResponse默认只能序列化字典 序列化其他需要加safe参数
return JsonResponse(l,safe=False)
form表单上传文件
'''
form 表单上传文件类型数据需要注意以下两点
1. method必须指定成post
2. enctype必须换成formadta
'''
前端代码
<form action="" method="post" enctype="multipart/form-data">
<p>username: <input type="text" name="username"></p>
<p>file:<input type="file" name="file"></p>
<input type="submit" value="提交">
</form>
views.py
def ab_file(request):
if request.method == 'POST':
print(request.POST)
print(request.FILES) # 获取文件数据
file_obj = request.FILES.get('file') # 获取文件对象
with open(file_obj.name,'wb') as f:
for line in file_obj.chunks(): # 推荐加上chunks方法 其实跟不加是一样的
f.write(line)
return render(request, 'form.html')
request对象方法
"""
request.method
request.POST
request.GET
request.FILES
request.body # 原生的浏览器发过来的二进制数据
request.path # 获取完整url
request.path_info # 获取完整url
request.get_full_path() 能过获取完整的url及问号后面的参数
"""
print(request.path) # /app01/ab_file/
print(request.path_info) # /app01/ab_file/
print(request.get_full_path()) # /app01/ab_file/?username=jason
FBV和CBV
# 视图函数既可以是函数也可以是类
def index(request):
return HttpResponse('index')
FBV
def index(request):
return HttpResponse('FBV')
CBV
# CBV路由
url(r'^login/',views.MyLogin.as_view())
# views.py
from django.views import View
class MyLogin(View):
def get(self,request):
return render(request,'form.html')
def post(self,request):
return HttpResponse('post方法')
"""
FBV和CBV各有千秋,request形参是必不可少的
CBV特点
能够直接根据请求方式的不同直接匹配到对应的方法执行
"""
CBV源码剖析总结
注意: 不要轻易修改源码
通过urls.py中的路由分发
url(r'^login/',views.MyLogin.as_view())
'''
函数名/方法名 加括号执行优先级最高
'''
as_view()主要源码
@classonlymethod # 继承了classmethod 方法 只能被类调用
def as_view(cls, **initkwargs):
'''
as_view 被类方法修饰,cls就是我们自己写的类
'''
def view(request, *args, **kwargs):
self = cls(**initkwargs) # cls是我们自己写的类
# self = MyLogin(**initkwargs) 产生一个我们自己写的类的对象
return self.dispatch(request, *args, **kwargs)
return view
'''
as_view方法返回值是view方法,此时
views.MyLogin.as_view() 等同于 views.view
这时,我们可以发现view方法返回值是self.dispatch(request, *args, **kwargs)
'''
dispatch(request, *args, **kwargs)主要源码
# CBV的精髓所在
def dispatch(self, request, *args, **kwargs):
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
"""
反射:通过字符串来操作对象的属性或者方法
handler = getattr(自己写的类产生的对象,'get',当找不到get属性或者方法的时候就会用第三个参数)
handler = 我们自己写的类里面的get方法
"""
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
'''自动调用get方法'''