无名,有名分组、反向解析;路由分发;JsonResponse对象;request对象的其他方法;CBV源码解析 # day53
无名分组
在路由urls.py文件中
# \d => [0-9], 之后加上加好代表至少一个,一个到多个的意思
# url(r'^index/\d+', views.index) #这种语法在index/之后最少也要加上一个数字才能查到返回值,不加数字查不到方法的返回值。
# url(r'^index/(\d+)', views.index), #index/后面匹配的参数条件用小括号括起来,相应的在视图函数中的函数方法中必须多传一个形参,可以用来获取index/后面输入的值
def index(request, xxx):
print(xxx)
return HttpResponse("index")
# 无名分组就是将路由后面匹配的参数用小括号括起来,以位置参数的形式传递给视图函数
# 无名分组路由后面匹配的参数可以有多个,对应的必须有多个位置参数传递给视图函数
有名分组
# 给无名分组用?P<aaa>在括号内起了个aaa的名字,在此起的名字必须跟视图函数中所多传的形参名字一样
# url(r'^test/(?P<aaa>\d+)', views.test),
def index(request, aaa):
print(aaa)
return HttpResponse("index")
# 有名分组就是将路由后面匹配的参数用小括号括起来,以关键字参数的形式传递给视图函数
# 当匹配参数有多个,可用**kwargs来接收多个参数
是否可以结合使用
url(r'^test1/(\d+)/(?P<id>\d+)/$',views.test1)
1.无名有名分组不能混合使用
url(r'^test2/(\d+)/(\d+)/$',views.test2),
url(r'^test2/(?P<id>\d+)/(?P<id1>\d+)/$',views.test2)
2.可以单个重复使用
反向解析
当路由频繁变化的时候,html界面上的连接地址如何做到动态解析
# 1.给路由与视图函数对应关系添加一个别名(名字自己指定 只要不冲突即可)
url(r'^index/',views.index,name='index_name')
# 2.根据该别名动态解析出一个结果,该结果可以直接访问到对应的路由
前端
<a href="{% url 'index_name' %}">111</a>
后端
from django.shortcuts import reverse
reverse('index_name')
ps:redirect括号内也可以直接写别名
```
无名有名反向解析
无名反向解析
url(r'^index/(\d+)/',views.index,name='index_name')
后端
reverse('index_name',args=(1,)) # 只要给个数字即可
前端
<a href="{% url 'index_name' 1 %}"></a> # 只要给个数字即可
有名反向解析
url(r'^index/(?P<id>\d+)/',views.index,name='index_name')
后端
reverse('index_name',kwargs={'id':123}) # 只要给个数字即可
前端
<a href="{% url 'index_name' id=666 %}"></a> # 只要给个数字即可
总结
无名有名都可以使用一种(无名)反向解析的形式
路由分发
# 总路由就不再写路由与视图函数的对应关系, 用来识别当前路由属于哪一个应用
from django.conf.urls import url,include # 需要导入include模块
# 第一种方式
from app01 import urls as app01_urls
from app02 import urls as app02_urls
from app01 import views
urlpatterns = [
url(r'app01/', include(app01_urls)),
url(r'app02/', include(app02_urls)),
]
# 强调:总路由中,最后面千万不能加$
# 第二种方式
urlpatterns = [
url(r'app01/', include('app01.urls')),
url(r'app02/', include('app02.urls')),
]
JsonResponse对象
# json格式的数据有设么用?
实现前后端数据交互的一种数据格式,实现跨语言之间的通信
from django.http import JsonResponse
import json
def a_json(request):
user_dic = {'name': 'ly洋哥很帅', 'age': 18}
l = [1, 2, 3,4]
# res = json.dumps(user_dic, ensure_ascii=False)
# res = JsonResponse(user_dic, json_dumps_params={'ensure_ascii': False})
res = JsonResponse(l,safe=False)
return HttpResponse(res)
request对象中的其他方法
request.method
request.GET.get()
request.GET.getlist()
request.POST.get()
request.POST.getlist()
def func(request):
# 上传文件必须做的两件事:
# 1. 请求方式改成post
# 2. 改enctype=multipart/form-data
# print(request.POST)
# <MultiValueDict: {'myfile': [<InMemoryUploadedFile: 123.png (image/png)>]}>
# print(request.FILES.get('myfile'))
"""
/app01/func/
/app01/func/
/app01/func/
/app01/func/
/app01/func/
/app01/func/?name=ly
:param request:
:return:
"""
print(request.path)
print(request.path_info)
print(request.get_full_path())
return render(request, 'func.html')
FBV与CBV的书写
FBV
基于函数的视图
CBV
基于类的视图
# 基本使用
from django.views import View
class MyView(View):
def get(self,request):
return HttpResponse("get方法")
def post(self,request):
return HttpResponse("post方法")
url(r'^func4',views.MyView.as_view())
"""为什么能够自动根据请求方法的不同执行不同的方法"""
1.突破口
as_view()
2.CBV与FBV路由匹配本质
url(r'^func4',views.MyView.as_view())
# 等价 CBV路由配置本质跟FBV一样
# url(r'^func4',views.view)
3.源码
def as_view(cls, **initkwargs):
def view(request, *args, **kwargs):
self = cls(**initkwargs) # self = MyView() 生成一个我们自己写的类的对象
return self.dispatch(request, *args, **kwargs)
return view
def dispatch(self, request, *args, **kwargs):
# 获取当前请求并判断是否属于正常的请求(8个)
if request.method.lower() in self.http_method_names:
# get请求 getattr(对象,'get') handler = 我们自己写的get方法
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs) # 执行我们写的get方法并返回该方法的返回值
扩展
python setattr()、getattr()、hasattr() 函数用法介绍
一.函数介绍
在动态检查对象是否包含某些属性(包括方法〉相关的函数有如下几个:
- hasattr(object,name):检查 object 对象是否包含名为 name 的属性或方法。
- getattr(object,name,default=None):获取 object 对象中名为 name 的属性的属性值(属性和函数都叫做属性)。
- setattr(object,name,value):将 object 对象的 name 属性设为 value。
1 class Learn_Python:
2 def __init__(self, detail, view_times):
3 self.detail = detail
4 self.view_times = view_times
5
6 def start(self):
7 print("尝试学习%s" % self.detail)
8
9
10 c = Learn_Python('python自动化', 20)
二.hasatter()函数使用
1)判断类中存在的属性和方法
1 # 判断是否包含指定的属性或方法
2 print(hasattr(c, 'detail')) # True
3 print(hasattr(c, 'view_times')) # True
4 print(hasattr(c, 'start')) # True
2)判断类中不存在的属性和方法
1 # 判断是否包含指定的属性或方法
2 print(hasattr(c, 'detail_1')) # False
3 print(hasattr(c, 'view_times_1')) # False
4 print(hasattr(c, 'start_1')) # False
二.getattr()函数使用
1)获取类中存在的属性
1 # 获取指定属性的属性值和方法
2 print(getattr(c, 'detail')) # 'python自动化'
3 print(getattr(c, 'view_times')) # 20
4 print(getattr(c, 'start')) # <bound method Learn_Python.start of <__main__.Learn_Python object at 0x0000020EC839E3C8>>
2)获取类中不存在的属性
结果直接报错
3)获取类中不存在的属性,并且给它默认值(这个默认值可以自己定义)
1 #获取不存在的属性,并且给默认值
2 print(getattr(c, 'start', '默认值')) #<bound method Learn_Python.start of <__main__.Learn_Python object at 0x00000163F6D08B38>>
二.hasattr()函数使用
1)指定属性设置为新属性值
1 #为指定属性设置属性值
2 setattr(c, 'detail', 'python接口自动化')
3 setattr(c, 'view_times', 32)
4 #输出重新设置后的属性值
5 print(c.detail) #python接口自动化
6 print(c.view_times) #32
2)为对象添加不存在的属性值
1 #为对象添加不存在的属性值
2 setattr(c, 'detail_1', 'python接口自动化') #不存在的detail_1属性值
3 #输出重新设置后的属性值
4 print(c.detail_1) #python接口自动化
3)指定方法设置为新的方法
1 def end ():
2 print('随便的方法')
3 # 将c的start方法设为end函数
4 setattr(c, 'start', end)
5 c.start() #随便的方法
4)为对象添加不存在的方法
1 def end ():
2 print('随便的方法')
3 # 为对象添加不存在的end函数
4 setattr(c, "start_1",end) #不存在的方法start_1
5 c.start_1() #随便的方法
5)指定方法设置为属性(不能将方法变为属性值)
1 def end ():
2 print('随便的方法')
3 # 将c的start方法设为end函数
4 setattr(c, 'start', "end")
5 c.start() #TypeError: 'str' object is not callable


浙公网安备 33010602011771号