Django之视图

1. 视图 View

Django之视图

视图 View
  • 一个视图函数(类),简称视图,是一个简单的Python函数(类),它接受web请求并且返回web响应。
  • 响应可以是一个网页的html内容,一个重定向,一个404错误,一个xml文档,或者一张图片。
  • Django使用请求和响应对象来通过系统传递状态。每个视图函数都使用HttpRequest对象作为第一个参数,并且通常称之为request。
  • 当浏览器向服务器请求一个页面时,Django创建一个HttpRequest对象,该对象包含关于请求的元数据。然后,Django加载相应的视图,将这个HttpRequest对象作为第一个参数传递给视图函数,每个视图负责返回一个HttpResponse对象
  • 在MVC模式中,视图代表的是html页面的内容;在MTV模式中,视图是用来处理业务逻辑的
1.1 FBV和CBV
FBV和CBV
FBV Function Based View
def xxx(request):
	#处理业务逻辑
	return response
#url.py
url(r'xxx/,xxx')
def publisher_add(request):
    if request.method == 'POST':
        pub_name = request.POST.get('pub_name')
        if not pub_name:
            error = '输入不能为空'
            return render(request,'publisher_add.html',{'error':error})
        if models.Publisher.objects.filter(name=pub_name):
            error = '出版社名称已存在'
            return render(request,'publisher_add.html',{'error':error})
        ret = models.Publisher.objects.create(name=pub_name)
        return redirect('/app01/publisher_list/')
    return render(request,'publisher_add.html')

CBV Class Based View

from django.views import View
class PublisherAdd(View):

	def get(self,reqest):
		#处理get请求
		使用self.request获取请求信息和request一样,因为在执行as_view的view方法时,对request对象进行了封装
		return response
		
	def post(self,reqest):
		#处理post请求
		return response
#url.py
url(r'publisher_add/',PublisherAdd.as_view())
class PublisherAdd(View):

    def get(self,request):
        return render(request,'publisher_add.html')

    def post(self,request):
        pub_name = request.POST.get('pub_name')
        error = ''
        if not pub_name:
            error = '输入不能为空'
            return render(request,'publisher_add.html',{'error':error})
        if models.Publisher.objects.filter(name=pub_name):
            error = '出版社名称已存在'
            return render(request,'publisher_add.html',{'error':error})
        else:
            models.Publisher.objects.create(name=pub_name)
            return redirect('/app01/publisher_list/')
  • Django中的类视图拥有自动查找制定方法的功能,通过调用as_view()方法实现。
  • 设计思想:把视图函数的逻辑定义到类的方法里,然后在函数中实例化这个类,通过调用类的方法实现函数逻辑。而把逻辑定义到类中的一个好处就是可以通过继承复用这些方法。
  • as_view(类方法)的执行流程:
  1. 程序加载时,执行PublisherAdd.as_view(),as_view返回值是view函数名,即返回一个view函数(as_view内的view函数)
  2. 程序执行时,执行view函数
    1. 实例化所调用的类,即PublisherAdd,并将PublisherAdd实例化对象赋值给self;
    2. self.request = request ,封装request对象
    3. 对象执行self.dispatch方法
      1. 判断请求是否被允许
        1. 允许
          • 通过反射获取请求方式对应请求方法,将结果返回给handler;
          • 获取不到self.http_method_not_allowed方法返回值赋值给handler;
        2. 不允许
          • self.http_method_not_allowed方法返回值赋值给handler;
      2. 执行handler 将方法的结果返回
  • 调用顺序:as_view–>view–>dispatch
    • 可以看出as_view实际上是一个闭包,作用就是做一些检验工作,再返回view方法
    • view方法的作用是给请求对象补充三个参数(self.request, self.args, self.kwargs),并调用dispatch方法处理
    • dispatch方法查找到指定的请求方法,并执行相应代码块
1.2 给视图加装饰器
给视图加装饰器
  • FBV
    • 直接加,FBV本身就是一个函数,所以和普通的函数加装饰器无差别
  • CBV
    from django.utils.decorators import method_decorator
    
    1.加在方法上
    @method_decorator(timer)
    def get(self,request):
        return render(request,'publisher_add.html')
        
    2.加在dispatch方法上(在PublisherAdd类中重写dispatch方法)
    @method_decorator(timer)
    def dispatch(self,request,*args,**kwargs): 
         ret = super().dispatch(self,request,*args,**kwargs)    # 执行View中的dispatch方法
         return ret
    
    @method_decorator(timer,name='dispatch')
    class PublisherAdd(View):
    
    3.加在类上
    @method_decorator(timer,name='get')
    @method_decorator(timer,name='post')
    class PublisherAdd(View):
    
1.3 Request对象
Request对象
  • 当页面被请求时,Django就会创建一个包含本次请求原信息的HttpRequest对象
  • Django会将这个对象自动传递给响应的视图函数,一般视图函数约定俗成地使用request参数承接这个对象

属性:

  • request.method 一个字符串,表示请求中使用的HTTP方法,全大写表示
    • 请求方式  GET POST
  • request.GET  包含所有HTTP GET参数的类字典对象
    • url上携带的参数  ?k1=v1&k2=v2  以字典形式传递给后台{ } request.GET[‘k1’] /request.GET.get(‘k1’)
  • request.POST  包含所有HTTP GET参数的类字典对象
    • POST请求提交的数据,如果请求中包含表单数据,则将这些数据封装成QueryDict对象
    • 以字典形式传递给后台{ } 编码格式是urlencode
    • POST 请求可以带有空的 POST 字典 —— 如果通过 HTTP POST 方法发送一个表单,但是表单中没有任何的数据,QueryDict 对象依然会被创建。因此,不应该使用 if request.POST 来检查使用的是否是POST 方法;应该使用 if request.method == “POST”
  • request.body  一个字符串,代表请求报文的主体。
    • 请求体,byte类型 request.POST的数据就是从body里面取到的
  • request.FILES  一个类似于字典的对象,包含所有的上传文件信息
    • FILES中的每个键为<input type=“file” name="" / >中的name,值则为对应的数据
    • FILES只有在POST请求时,且提交的标签带有enctype=“multipart/form-data” 的情况下才会包含数据,否则,FILES将为一个空的类似于字典的对象
    上传文件示例:
    .html
    <form action="" method="post" enctype="multipart/form-data" >
    	<input type="file" name="index">
    	<button>上传</button>
    </form>
    
    #view.py
    f1=request.FILES.get('ffff')
    f1.name  #获取上传文件的名字
    
    for i in f1:
    	f.write(i)
    	
    def upload(request):
        if request.method == "POST":
            # 从请求的FILES中获取上传文件的文件名,index为页面上type=files类型input的name属性值
            filename = request.FILES["index"].name
            # 在项目目录下新建一个文件
            with open(filename, "wb") as f:
                # 从上传的文件对象中一点一点读
                for chunk in request.FILES["index"].chunks():
                    # 写入本地文件
                    f.write(chunk)
            return HttpResponse("上传OK")
    
  • request.META 一个标准的python字典,包含所有HTTP头部信息
    • 请求中的任何 HTTP 头部转换为 META 的键时,都会将所有字母大写并将连接符(-)替换为下划线(_),最后加上 HTTP_ 前缀。
    • Accept-Language 转换成META 的键为 HTTP_ACCEPT_ENCODING
  • request.path_info  返回用户访问的url,不包括域名
  • rrequest.COOKIES cookie的信息
  • request.session session的信息

方法:

  • request.get_full_path()  完整的路径,不包含IP和端口号,包含参数 ?k1=v1&k2=v2
  • request.is_ajax()  是否是ajax请求,如果请求是通过XMLHttpRequest 发起的,则返回True
1.4 Response对象
Response对象

  Django服务器接收到客户端发送过来的请求后,会将提交上来的这些数据封装成一个 HttpRequest 对象传给视图函数。那么视图函数在处理完相关的逻辑后,也需要返回一个响应给浏览器。而这个响应,我们必须返回 HttpResponseBase 或者他的子类的对象。而 HttpResponse 则是 HttpResponseBase 用得最多的子类。

HttpResponse

  • HttpResponse(”字符串") 返回字符串
  • HttpResponse.content:响应内容
  • HttpResponse.charset:响应内容的编码
  • HttpResponse.status_code:响应的状态码

render

  • 结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的HttpResponse对象
  • render(request,“模板的文件名”,{ })
def render(request, template_name, context=None, content_type=None, status=None, using=None):
    """
    Returns a HttpResponse whose content is filled with the result of calling
    django.template.loader.render_to_string() with the passed arguments.
    """
    content = loader.render_to_string(template_name, context, request, using=using)
    return HttpResponse(content, content_type, status)
  • request:用于生成响应的对象
  • template_name:要使用的模板的完整名称,可选参数
  • context:添加到模板上下文的一个字典,默认是一个空字典。如果字典中的值是可调用的,视图将在渲染模板前调用它
  • content_type:生成的文档要使用的MIME类型,默认为"text/html"
  • status:响应的状态码,默认为200
  • using:用于加载模板的模板引擎的名称

redirect

  • redirect(“地址”) 重定向 Location:“地址” 状态码301(永久重定向) 302(临时重定向)
  • 默认情况下,redirect()返回一个临时重定向,一下三种形式都接收一个permanent参数;如果设置为True,将返回一个永久重定向。
  • 参数可以是:
    • 一个模型(一个具体的ORM对象):将调用模型的get_absolute_url() 函数
    • 一个视图,可以带有参数:将使用urlresolvers.reverse 来反向解析名称
    • 一个绝对的或相对的URL,将原封不动的作为重定向的位置。
from django.shortcuts import redirect

1.传递一个具体的ORM对象(模型):
def my_view(request):
    ...
    object = MyModel.objects.get(...)
    return redirect(object)
    
2.传递一个视图的名称
def my_view(request):
    ...
    return redirect('some-view-name', foo='bar')
    
3.传递要重定向到的一个具体的网址
def my_view(request):
    ...
    return redirect('/some/url/')
    # return redirect('http://example.com/')   也可以是一个完整的网址

JsonResponse

  • JsonResponse({ }) Content-Type = application/json JsonResponse([ ],safe=False)
  • JsonResponse是HttpResponse的子类,专门用来生成JSON编码的响应,且Content-Type = application/json
from django.http import JsonResponse

def index(request):
	# response = JsonResponse({'name': 'alex','age':18})
	# print(response.content)
	return JsonResponse({'name': 'alex','age':18})
  • 默认只能传递字典类型,如果要传递非字典类型需要设置一下safe关键字参数。
from django.http import JsonResponse

def index(request):
	persons = ["张三","李四","王五"]
	return JsonResponse(persons,safe=False)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值