django ----视图和路由

耗尽温柔 提交于 2020-01-01 05:05:06

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 列表) 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!