zoukankan      html  css  js  c++  java
  • 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 列表) 

  • 相关阅读:
    poj 1789 每个字符串不同的字母数代表两个结点间的权值 (MST)
    poj 1251 poj 1258 hdu 1863 poj 1287 poj 2421 hdu 1233 最小生成树模板题
    poj 1631 最多能有多少条不交叉的线 最大非降子序列 (LIS)
    hdu 5256 最少修改多少个数 能使原数列严格递增 (LIS)
    hdu 1025 上面n个点与下面n个点对应连线 求最多能连有多少条不相交的线 (LIS)
    Gym 100512F Funny Game (博弈+数论)
    UVa 12714 Two Points Revisited (水题,计算几何)
    UVa 12717 Fiasco (BFS模拟)
    UVa 12718 Dromicpalin Substrings (暴力)
    UVa 12716 && UVaLive 6657 GCD XOR (数论)
  • 原文地址:https://www.cnblogs.com/systemsystem/p/10311982.html
Copyright © 2011-2022 走看看