路由分发、名称空间、视图层之必会的三板斧、JsonResponse对象、request获取文件、FBV与CBV、模板层语法传值

路由分发、名称空间、视图层之必会的三板斧、JsonResponse对象、request获取文件、FBV与CBV、模板层语法传值

一、昨日内容回顾

二、路由分发

1.djiango的每个应用都有主见的templates文件夹,djiango文件夹,static文件夹等有利于分组
2.路由分发有益于防止总路由urls.py的代码冗余
3.组长可以将组员写的APP全部拷到一个新的djiango项目中,利用路由分发的特点整合app

img

总路由:
from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('app01/',include('app01.urls')),
    path('app02/',include('app02.urls'))
]
app01
urls.py:
from django.urls import path
from app01 import views
urlpatterns = [
    path('index/', views.index_urls),
]
views.py:
from django.shortcuts import render,HttpResponse

# Create your views here.
def index_urls(request):
    return HttpResponse('from app01 index urls')
app02
urls.py:
from django.urls import path
from app02 import views
urlpatterns = [
    path('index/', views.index_urls),
]
views:
from django.shortcuts import render,HttpResponse

# Create your views here.
def index_urls(request):
    return HttpResponse('from app02 index urls')

image

image

三、名称空间

当多个应用出现了相同的别名时,无法识别应用的前缀

解决方式一:名称空间

总的路由添加一个名称空间:
path('app01/',include(('app01.urls','app01'),namespace='app01')),
path('app02/',include(('app02.urls','app02'),namespace='app02'))
urls:
urlpatterns = [
    path('index/', views.index_urls, name='index_urls'),
]
views:
def index_urls(request):
    print(reverse('app01:index_urls'))
    return HttpResponse('from app01 index urls')

解决方式二:起别名

总路由:
path('app01/',include('app01.urls')),
path('app02/',include('app02.urls'))
子路由:
urls:
urlpatterns = [
    path('index/', views.index_urls, name='app01_index_urls'),
]
views:
def index_urls(request):
    print(reverse('app01_index_urls'))
    return HttpResponse('from app01 index urls')
1.只要名字不冲突,就没有必要使用名称空间
2.起别名我们一般在APP多的情况下,然后起别名的时候加上app当做前缀,这样就可以避免名字冲突的问题。

四、虚拟环境

虚拟环境的作用:
开发工作中针对不同的项目需要为其配备对应的解释器环境
诸多项目在你的机器上任何无障碍的打开并运行
#方式1:
把所用的模块都下载下来,如果有相同模块不同版本每次都重新下载替换
#方式2:
提前准备好多个解释器环境,针对不同的项目切换

img

有一个新的文件夹创建讲师表示虚拟环境创建成功

img

命令行创建虚拟环境的方式:
    python -m venv xxxxxx
激活虚拟环境:
    activate
关闭虚拟环境:
    deactivate

img

五、视图层之必会三板斧

views.py文件里面是一系列的函数或者类
用来处理请求的视图函数都必须返回HttpResponse对象
1.HttpResponse
     返回的是字符串类型
     HttpResponse()括号内直接跟一个具体的字符串作为响应体
2.render
     返回html页面,并且在返回给浏览器之前还可以给HTML文件传值
     除了request参数外,还接受一个待渲染的模板文件和一个保存具体数据的字典参数
     def render(request, template_name, context=None, content_type=None, status=None, using=None)
     eg:def render(request,"index.html",{'form':form})
3. redirect
     接受一个url参数,表示跳转到指定的url
     eg: def redirect("/home")
研究底层源码
1.def index_func(request):
    return HttpResponse()
"""
按住ctrl键点击进入HttpResponse,进去之后发现HttpResponse其实是一个类
     类名加()就是实例化一个对象
     class HttpResponse(HttpResponseBase):
         def __init__(self,content,*args,**kwargs)
             pass
"""
2.def index(request):
    return render()
"""
 按住ctrl键点击进入render:
   def render(request, template_name, context=None, content_type=None, status=None, using=None):
    content = loader.render_to_string(template_name, context, request, using=using)
    return HttpResponse(content, content_type, status)
    执行的是render函数,然后render函数返回的是HttpResponse(content, content_type, status)
"""
3.def index(request):
    return redirect()
"""
按住ctrl键点击进入redirect:
  def redirect(to, *args, permanent=False, **kwargs):
    redirect_class = HttpResponsePermanentRedirect if permanent else HttpResponseRedirect
    return redirect_class(resolve_url(to, *args, **kwargs))

按住ctrl键点击进入HttpResponsePermanentRedirect:
    class HttpResponsePermanentRedirect(HttpResponseRedirectBase):
        status_code = 301
        ........
            
 最后发现它继承的也是HttpResponse
"""
综上:Django视图层函数必须要返回一个HttpResponse对象

六、JsonResponse对象

def index(request):
    user_dict = {'name':'jia老师','age':18}
    import json
    user_json = json.dumps(user_dict,ensure_ascii=False)   # 
    return HttpResponse(user_json)
from django.http import JsonResponse
def index(request):
    # user_dict = {'name':'jia老师','age':18}
    # import json
    # user_json = json.dumps(user_dict,ensure_ascii=False)
    # return HttpResponse(user_json)
    l1 = [11,22,33,44,55,66]
    return JsonResponse(l1,json_dumps_params={'ensure_ascii':False},safe=False)

查看源码发现扩展的功能
	class JsonResponse():
        def __init__(self,data,json_dumps_params=None):
        		json.dumps(data,**json_dumps_params)        
JsonResponse主要序列化字典 针对非字典的其他可以被序列化的数据需要修改safe参数为False

image

七、视图层之request对象获取文件

html代码:
<h1>获取数据</h1>
      <form action="" method="post" enctype="multipart/form-data">
          <p>
              username:
              <input type="text" name="username">
          </p>
          <p>
              hobby:
              <input type="checkbox" name="hobby" value="basketball">篮球
              <input type="checkbox" name="hobby" value="basketball1">篮球1
              <input type="checkbox" name="hobby" value="basketball2">篮球2
          </p>
          <p>
              file:
              <input type="file" name="file">
          </p>
          <input type="submit" value="按钮">
          <button>按钮</button>
      </form>
    if request.method == 'Post':
        print(request.POST)
        print(request.FILES)
    return render(request,'1.html')

image

    if request.method == 'POST':
        # print(request.POST)
        # print(request.FILES)

        file_obj = request.FILES.get('file')
        print(file_obj.name)
        with open(r'%s' % file_obj.name, 'wb') as f:
            for line in file_obj:
                f.write(line)
    return render(request,'1.html')

八、FBV与CBV

FBV(Function base view):基于函数的视图 我们之前写过的都是FBV
CBV(Class base view)
1.FBV
  def index(request):
        return HttpResponse对象
2.CBV
 from django import views
 class MyLoginView(views.View):
    def get(self, request):
        return HttpResponse('from CBV get function')

    def post(self, request):
        return HttpResponse('from CBV post function')
    path('login/', views.MyLoginView.as_view())

九、CBV源码剖析

path('login/', views.MyLoginView.as_view())
"""
  面向对象属性方法的查找顺序:
     1.先从对象自己的名称空间找
     2.去产生类对象的类里面找
     3.去父类里面找
"""
源码分析入口
	path('func/', views.MyView.as_view())
	1.绑定给类的as_view方法(它是我们自己写的类里面继承的类)
		class View:
			@classonlymethod
			def as_view(...):
			绑定给类的,类调用会自动将类当作第一个参数传入
				def view(...):
					pass
				return view
	2.CBV路由匹配本质:跟FBV是一致的
		path('func/', views.view)
	3.访问func触发view执行
		def view(...):
			obj = cls()  # 我们自己写的类加括号产生的对象
			return obj.dispatch()
		'''涉及到对象点名字 一定要确定对象是谁 再确定查找顺序'''
	4.研究dispatch方法
		def dispatch(...):
			判断 request.method将当前请求方式转成小写 在不在 self内 self==MyLogin 
			"http_method_names 内有八个请求方式 合法"
    ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
			if request.method.lower() in self.http_method_names:
				# getattr 反射: 通过字符串来操作对象的属性或者方法
				func_name = getattr(obj,request.method.lower())
			else:
				handler = self.http_method_not_allowed
			return handler(request, *args, **kwargs)
		用到了一个反射的知识,从obj这个对象里面,找一个request.method.lower()这个的函数

十、模板层

1.模板语法的传值

urls代码:
path('modal/', views.modal)

views代码:
def modal(request):
    name = 'jason'
    return  render(request, 'modal.html', {'name':name})

指名道姓传参 不浪费资源
html代码:
<body>
    {{ name }}
    {{ age }}
    {{ gender }}
</body>

urls代码:
path('modal/', views.modal)

views代码:
def modal(request):
    name = 'jason'
    age = 18
    gender = 'female'
    return render(request, 'modal.html', locals())  # 将函数体里局部空间里所有的名字全部传入给前面的那个页面

将整个局部名称空间中的名字去全部传入简单快捷

2.模板语法传值特性

    1.基本数据类型正常展示
    2.文件对象也可以展示并调用方法
    3.函数名会自动加括号执行并将返回值展示到页面上(不支持额外传参)
    4.类名也会自动加括号调用
    5.对象则不会	
	 ps:总结针对可以加括号调用的名字模板语法都会自动加括号调用
posted @ 2022-12-13 22:08  小王应该在学习!  阅读(46)  评论(0编辑  收藏  举报