django框架

7,877 阅读6分钟

名称空间

路由分发之后 针对相同的别名能否自动反向解析出不同的应用前缀   默认情况下是无法识别应用前缀的  

如果想要正常识别区分有两种方式 
   方式1:名称空间
      总路由      
      

image.png

反向解析:reverse("app名称:路由别名")


   方式2:别名不冲突就可以
       多个应用别名不冲突可以用应用名作为别名的前缀
path('index/',views.index,name='app01_index_view')
path('index/',views.index,name='app02_index_view')
存在问题:路由别名 name 没有作用域,Django 在反向解析 URL 时,会在项目全局顺序搜索,当查找到第一个路由别名 name 指定 URL 时,立即返回。当在不同的 app 目录下的urls 中定义相同的路由别名 name 时,可能会导致 URL 反向解析错误。

解决: 使用命名空间。
普通路径:定义命名空间(include 里面是一个元组)格式如下:include(("app名称:urls""app名称"))

虚拟环境

安装python的时候相当于安装了一个全局的环境:

  • site-packages目录下是python第三方包(也就是pip install 安装的包都在该目录下)

  • 标准库就是原生库(os,sys, math 等等)

  • Scripts下是可执行文件(pip install 时就会使用pip.exe这个可执行文件)

  • python.exe就是python解释器

  • 虚拟环境可以看作是原生Python的副本,但是标准库都是一样的,每次都复制是不合算的

  • 所以每次就不复制标准库,而是直接调用原来的标准库就行。

  • 同时解释器也存到Scripts这个目录下,path环境变量只需要增加一个即可。

  • 虚拟环境:能够针对相同版本的解释器创建多个分身 每个分身可以有自己独立的环境

  • pycharm创建虚拟环境:每创建一个虚拟环境就相当于重新下载了一个全新的解释器

  • 在这里要注意的是python不支持多版本共存的操作
    激活:activate 关闭:deactivate

image.png

image.png

视图层必会三板斧

用来处理请求的是视图函数都必须返回HttpResponse

class HttpResponse:
    pass
return HttpResponse()	

def render():
    return HttpResponse()
return render()

def redirect():
    redirect_class = 类(祖先有个类是HttpResponse)
    return redirect_class()
return redirect()

JsonResponse对象

from django.http import JsonResponse
def index_func(request):
    # return HttpResponse('哈哈哈')
    # return render()
    # return redirect()
    # 返回给浏览器一个json格式的字符串
    user_dict = {'name': 'jason老师', 'age': 18}
    # import json
    # user_json = json.dumps(user_dict, ensure_ascii=False)
    # return HttpResponse(user_json)
    return JsonResponse(user_dict)

以后写代码很多时候可能需要参考源码及所学知识扩展功能
        class JsonResponse():
        def __init__(self,data,json_dumps_params=None):
                        json.dumps(data,**json_dumps_params)

JsonResponse主要序列化字典 针对非字典的其他可以被序列化的数据需要修改safe参数为False

视图层之request对象获取文件

form表单携带文件类型的数据需要做到以下几点
        1.method必须是post
        2.enctype必须是multipart/form-data
django后端需要通过request.FILES获取文件类型的数据

视图层之FBV与CBV

FBV

  • 基于函数的视图其实我们前面章节一直在使用,就是使用了函数来处理用户的请求

      urls.py 文件
          urlpatterns = [  
          path("login/", views.login),  
          ]
      views.py 文件
    
      from django.shortcuts import render,HttpResponse  
    
      def login(request):  
          if request.method == "GET":  
              return HttpResponse("GET 方法")  
          if request.method == "POST":  
              user = request.POST.get("user")  
              pwd = request.POST.get("pwd")  
              if user == "runoob" and pwd == "123456":  
                  return HttpResponse("POST 方法")  
              else:  
                  return HttpResponse("POST 方法1")
                  
    

CBV

  • 基于类的视图,就是使用了类来处理用户的请求,不同的请求我们可以在类中使用不同方法来处理,这样大大的提高了代码的可读性。

  • 定义的类要继承父类 View,所以需要先引入库: from django.views import View

  • 执行对应请求的方法前会优先执行 dispatch 方法(在get/post/put...方法前执行),dispatch() 方法会根据请求的不同调用相应的方法来处理。

  • Django 的 url 是将一个请求分配给可调用的函数的,而不是一个类, 主要还是通过父类 View 提供的一个静态方法 as_view() ,as_view 方法是基于类的外部接口, 他返回一个视图函数,调用后请求会传递给 dispatch 方法,dispatch 方法再根据不同请求来处理不同的方法。

      urls.py 文件
    
     urlpatterns = [  
         path("login/", views.Login.as_view()),  
     ]  
    
    
      views.py 文件
    
     from django.shortcuts import render,HttpResponse  
     from django.views import View  
    
     class Login(View):  
         def get(self,request):  
             return HttpResponse("GET 方法")  
    
         def post(self,request):  
             user = request.POST.get("user")  
             pwd = request.POST.get("pwd")  
             if user == "runoob" and pwd == "123456":  
                 return HttpResponse("POST 方法")  
             else:  
                 return HttpResponse("POST 方法 1")
                 
                 
    

CBV源码剖析

1.从CBV的路由匹配切入
        path('login/', views.MyLoginView.as_view())
        1.类名点名字(名字的查找问题)
        2.类名点名字并加括号调用(静态方法、绑定给类的方法)
2.函数名加括号执行优先级最高 项目一启动就会自动执行as_view方法
        path('login/', views.view)  # CBV路由本质还是FBV
3.浏览器地址栏访问login路由需要执行view函数
        1.产生我们自己编写类的对象
        2.对象调用dispatch方法(注意查找顺序)
4.研究父类中的dispatch方法
        获取当前请求方法并转小写 之后利用反射获取类中对应的方法并执行


class View:
     @classmethod
     def as_view(cls, **initkwargs):
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            return self.dispatch(request, *args, **kwargs)
     def dispatch(self, request, *args, **kwargs):
         handler = getattr(self, request.method.lower())
         return handler(request, *args, **kwargs)
         

模板层

{{}}:主要与数据值相关
{%%}:主要与逻辑相关

django的模板语法是自己写的 跟jinja2不一样

1.针对需要加括号调用的名字 django模板语法会自动加括号调用你只需要写名字就行
2.模板语法的注释前端浏览器是无法查看的 {##}
3.
"""

1.模板语法传值
    return render(request, 'demo02.html', {'n1': name, 'a1': age})  # 传值方式1:精准传值 不浪费资源 针对多资源的传递书写麻烦
    return render(request,'demo02.html', locals())  # 传值方式2:将函数名称空间中所有的名字全部传递 名字过多并且不使用的情况下比较浪费资源

2.模板语法传值特性
    1.基本数据类型正常展示
    2.文件对象也可以展示并调用方法
    3.函数名会自动加括号执行并将返回值展示到页面上(不支持额外传参)
    4.类名也会自动加括号调用
    5.对象则不会	
         ps:总结针对可以加括号调用的名字模板语法都会自动加括号调用

3.模板语法之过滤器(内置函数)
<p>统计数据的长度:{{ s1|length }}</p>
<p>算术加法或者字符串加法:{{ n1|add:111 }}、{{ s1|add:'big baby' }}</p>
<p>将数字转成合适的文件计量单位:{{ file_size|filesizeformat }}、{{ file_size1|filesizeformat }}</p>  # 返回KB\MB计量单位
<p>判断当前数据对象对应的布尔值是否是False:{{ b|default:'前面的值对应的布尔值是False' }}、{{ s1|default:'前面的值对应的布尔值是False' }}</p>
<p>时间格式化:{{ ctime|date:'Y-m-d' }}</p>
<p>索引切片:{{ s1|slice:'0:8' }}</p>
<p>按照空格截取指定个数的文本:{{ s2|truncatewords:5 }}、{{ s1|truncatewords:1 }}</p>  # 数字5表示截取5次 文本后面用...结尾 
<p>按照字符个数截取文本(包含三个点):{{ s2|truncatechars:5 }}、{{ s1|truncatechars:10 }}</p>  # 数字5表示截取2个字符加上...共五个字符
<p>移除指定的字符:{{ info|cut:'|' }}</p>  # cut(移除)
<p>是否取消转换:{{ tag1 }}、{{ tag1|safe }}、{{ scripts1|safe }}、{{ res }}</p>