• django ----视图和路由


    django的view(视图)

      一个视图函数,简称视图,是一个简单python函数,他接受web请求并且返回一个响应

      响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片。

      无论视图本身包含什么逻辑,都要返回响应。代码写在哪里也无所谓,只要它在你当前项目目录下面

    一 FBV (function based view) 基于函数视图

      例子 : 

    # FBV版添加班级
    def add_class(request):
        if request.method == "POST":
            class_name = request.POST.get("class_name")
            models.Classes.objects.create(name=class_name)
            return redirect("/class_list/")
        return render(request, "add_class.html")

    二 CBV (class based view) 基于类的视图

      例子 :

    # CBV版添加班级
    from django.views import View # 先引入这个包  
    
    
    class AddClass(View):  # 格式  写一个类 下面定义方法(请求方式) 这样写的好处是 不用判断是get换是post方式 
    
        def get(self, request):    
            return render(request, "add_class.html")
    
        def post(self, request):
            class_name = request.POST.get("class_name")
            models.Classes.objects.create(name=class_name)
            return redirect("/class_list/")

    注意:

    使用CBV时 urls.py中也要做对应的修改

    # urls.py中
    url(r'^add_class/$', views.AddClass.as_view()) 这个会自己区分get 和post请求

    三  给视图加装饰器

      FBV的:(他本身就是一个函数,所以和正常函数,没什么区别,正常在函数上面加就行) 

    def wrapper(func):
        def inner(*args, **kwargs):
            start_time = time.time()
            ret = func(*args, **kwargs)
            end_time = time.time()
            print("used:", end_time-start_time)
            return ret
        return inner
    
    
    # FBV版添加班级
    @wrapper
    def add_class(request):
        if request.method == "POST":
            class_name = request.POST.get("class_name")
            models.Classes.objects.create(name=class_name)
            return redirect("/class_list/")
        return render(request, "add_class.html")

      CBV的:(类中的方法与独立函数不完全相同,因此不能直接将函数装饰器应用于类中的方法,我们需要将其转换成方法

        方法装饰器)

        django给我们提供了 methed_decorator 用于将类中的函数转换成方法装饰器(先导入包

        from django.utils.decorators import method_decorator)

         加装饰器的三种方法:

          1,给某一个方法单独加装饰器:  @method_decorator(装饰器函数)

          2 给所有请求加 装饰器: 他源码里有个 self.dispatch(request, *args, **kwargs) 函数 self (自己的类) dispatch(这个方法里面有判断 他是get还是post 并通过映射的方式 返回结果) 所以:对了 还有一点 如果你自己的类中有这个方法 他就会优先找自己的(截胡)那你就可以把这个函数写在自己的类中,并在其上面,这样所有的方法都可以有了

           3 加在类上: 有个小问题就是你得指定是给哪一类请求 加装饰器:

           


    @method_decorator(装饰器函数,get) # 第三种方式
    @method_decorator(装饰器函数,post) # 第三种方式
    class Login(View):
        
      @method_decorator(装饰器函数) #第二种方法 
      def dispatch(self, request, *args, **kwargs): 
         print(
    'before')
         obj
    = super(Login,self).dispatch(request, *args, **kwargs)
        print(
    'after')

         return obj
      @method_decorator(装饰器函数) # 第一种方法
    def
    get(self,request):

    return render(request,'login.html')

      def post(self,request):
        print(request.POST.
    get('user'))

        return HttpResponse('Login.post')

    四 CBV视图加装饰器 如果不使用 提供的模板能用吗 ,区别在哪?

      

    func :     <function AddPublisher.get at 0x00000000042CF158>
    
    args:     (<app01.views.AddPublisher object at 0x000000000440E898>, <WSGIRequest: GET '/add_publisher/'>)
    
    func :     <function method_decorator.<locals>.dec.<locals>.wrapper.<locals>.bound_func at args:     0x00000000045C71E0>
    
    (<WSGIRequest: GET '/add_publisher/'>,)

    五 请求相关的常用值 

    path_info     返回用户访问url,不包括域名
    method        请求中使用的HTTP方法的字符串表示,全大写表示。
    GET              包含所有HTTP  GET参数的类字典对象
    POST           包含所有HTTP POST参数的类字典对象
    body            请求体,byte类型 request.POST的数据就是从body里面提取到的

    六  属性(request相关属性)

    属性:
      django将请求报文中的请求行、头部信息、内容主体封装成 HttpRequest 类中的属性。
       除了特殊说明的之外,其他均为只读的。
    
    
    0.HttpRequest.scheme
       表示请求方案的字符串(通常为http或https)
    
    1.HttpRequest.body
    
      一个字符串,代表请求报文的主体。在处理非 HTTP 形式的报文时非常有用,例如:二进制图片、XML,Json等。
    
      但是,如果要处理表单数据的时候,推荐还是使用 HttpRequest.POST 。
    
      另外,我们还可以用 python 的类文件方法去操作它,详情参考 HttpRequest.read() 。
    
     
    
    2.HttpRequest.path
    
      一个字符串,表示请求的路径组件(不含域名)。
    
      例如:"/music/bands/the_beatles/"
    
    
    
    3.HttpRequest.method
    
      一个字符串,表示请求使用的HTTP 方法。必须使用大写。
    
      例如:"GET""POST"
    
     
    
    4.HttpRequest.encoding
    
      一个字符串,表示提交的数据的编码方式(如果为 None 则表示使用 DEFAULT_CHARSET 的设置,默认为 'utf-8')。
       这个属性是可写的,你可以修改它来修改访问表单数据使用的编码。
       接下来对属性的任何访问(例如从 GET 或 POST 中读取数据)将使用新的 encoding 值。
       如果你知道表单数据的编码不是 DEFAULT_CHARSET ,则使用它。
    
     
    
    5.HttpRequest.GET 
    
      一个类似于字典的对象,包含 HTTP GET 的所有参数。详情请参考 QueryDict 对象。
    
     
    
    6.HttpRequest.POST
    
      一个类似于字典的对象,如果请求中包含表单数据,则将这些数据封装成 QueryDict 对象。
    
      POST 请求可以带有空的 POST 字典 —— 如果通过 HTTP POST 方法发送一个表单,但是表单中没有任何的数据,QueryDict 对象依然会被创建。
       因此,不应该使用 if request.POST  来检查使用的是否是POST 方法;应该使用 if request.method == "POST" 
    
      另外:如果使用 POST 上传文件的话,文件信息将包含在 FILES 属性中。
    
     7.HttpRequest.COOKIES
    
      一个标准的Python 字典,包含所有的cookie。键和值都为字符串。
    
     
    
    8.HttpRequest.FILES
    
      一个类似于字典的对象,包含所有的上传文件信息。
       FILES 中的每个键为<input type="file" name="" /> 中的name,值则为对应的数据。
    
      注意,FILES 只有在请求的方法为POST 且提交的<form> 带有enctype="multipart/form-data" 的情况下才会
       包含数据。否则,FILES 将为一个空的类似于字典的对象。
    
     
    
    9.HttpRequest.META
    
       一个标准的Python 字典,包含所有的HTTP 首部。具体的头部信息取决于客户端和服务器,下面是一些示例:
    
        CONTENT_LENGTH —— 请求的正文的长度(是一个字符串)。
        CONTENT_TYPE —— 请求的正文的MIME 类型。
        HTTP_ACCEPT —— 响应可接收的Content-Type。
        HTTP_ACCEPT_ENCODING —— 响应可接收的编码。
        HTTP_ACCEPT_LANGUAGE —— 响应可接收的语言。
        HTTP_HOST —— 客服端发送的HTTP Host 头部。
        HTTP_REFERER —— Referring 页面。
        HTTP_USER_AGENT —— 客户端的user-agent 字符串。
        QUERY_STRING —— 单个字符串形式的查询字符串(未解析过的形式)。
        REMOTE_ADDR —— 客户端的IP 地址。
        REMOTE_HOST —— 客户端的主机名。
        REMOTE_USER —— 服务器认证后的用户。
        REQUEST_METHOD —— 一个字符串,例如"GET""POST"。
        SERVER_NAME —— 服务器的主机名。
        SERVER_PORT —— 服务器的端口(是一个字符串)。
       从上面可以看到,除 CONTENT_LENGTH 和 CONTENT_TYPE 之外,请求中的任何 HTTP 首部转换为 META 的键时,
        都会将所有字母大写并将连接符替换为下划线最后加上 HTTP_  前缀。
        所以,一个叫做 X-Bender 的头部将转换成 META 中的 HTTP_X_BENDER 键。
    
     
    10.HttpRequest.user
    
      一个 AUTH_USER_MODEL 类型的对象,表示当前登录的用户。
    
      如果用户当前没有登录,user 将设置为 django.contrib.auth.models.AnonymousUser 的一个实例。你可以通过 is_authenticated() 区分它们。
    
        例如:
    
        if request.user.is_authenticated():
            # Do something for logged-in users.
        else:
            # Do something for anonymous users.
         
    
           user 只有当Django 启用 AuthenticationMiddleware 中间件时才可用。
    
         -------------------------------------------------------------------------------------
    
        匿名用户
        class models.AnonymousUser
    
        django.contrib.auth.models.AnonymousUser 类实现了django.contrib.auth.models.User 接口,但具有下面几个不同点:
    
        id 永远为None。
        username 永远为空字符串。
        get_username() 永远返回空字符串。
        is_staff 和 is_superuser 永远为False。
        is_active 永远为 False。
        groups 和 user_permissions 永远为空。
        is_anonymous() 返回True 而不是False。
        is_authenticated() 返回False 而不是True。
        set_password()、check_password()、save() 和delete() 引发 NotImplementedError。
        New in Django 1.8:
        新增 AnonymousUser.get_username() 以更好地模拟 django.contrib.auth.models.User。
    
     
    
    11.HttpRequest.session
    
       一个既可读又可写的类似于字典的对象,表示当前的会话。只有当Django 启用会话的支持时才可用。
        完整的细节参见会话的文档。
    
    request属性相关

    上传文件 

    def upload(request):
        if request.method == 'POST':
            print(request.POST)
            f1 = request.FILES.get('f1')  f1 获得的是一个文件对象
            with open(f1.name, 'wb') as f:
                for i in f1.chunks(): #  chunks大文件会自动切断,成一段一段的
                    f.write(i)
    
            return HttpResponse('上传成功')
    
        return render(request, 'upload.html')
    form表单指定编码方式enctype="multipart/form-data"

    八 request对象 和 reponse对象

     request属性和方法

    print(request.method)   # 请求方式  GET POST PUT
    print(request.GET)      # URL携带的参数  { ‘name’: ['alex']   }   []  .get('name')
    print(request.POST)     # POST请求提交的数据  { ‘name’: ['alex']   }   .getlist()
    print(request.path_info)  # 路径信息  不包含ip和端口 参数
    print(request.FILES)
    print(request.META)
    print(request.COOKIES)
    print(request.session)
    
    print(request.get_host()) 
    print(request.get_full_path())  # 路径信息  不包含ip和端口  带参数
    print(request.is_ajax())  # 判断是否是ajax请求

    reponse 属性

    HttpResponse('字符串 ')       ——》 页面展示 字符串
    
    render(request,'html文件名',  { k1:v1 })    ——》 返回一个完整HTML页面  
    
    redirect(’要跳转的地址‘)  ——》重定向     Location : 地址

    JsonResponse: 他跟json序列化不同的是响应头不同   , 他默认只能传字典,相传其他类型加safe=False

    from django.http import JsonResponse
    
    
    def json_data(request):
        data = {'id': 11, 'name': 'alex'}
        l1 = ['alex', 'peiqi']
    
        return JsonResponse(l1, safe=False)  # Content-Type: application/json

    序列化可以支持的类型(数字 字典 字符串 none 列表) 

  • 相关阅读:
    分层开发的优势
    分层开发的特点
    三层开发遵循的原则
    为什么需要分层
    什么是JNDI
    为什么需要JavaBean
    连接池中的连接对象是由谁创建的呢?
    什么是连接池技术
    为什么使用连接池?(为什么要使用JNDI)
    Servlet加载
  • 原文地址:https://www.cnblogs.com/systemsystem/p/10311982.html
Copyright © 2020-2023  润新知