[Django] Django(四) 视图基础

View视图层概述

Django中的视图层,负责处理用户的请求并返回响应。
一个视图,简单来说就是一个Python函数(View类更高级),用户接受web请求,同时返回web响应。响应可以是文本、HTML页面、图像…视图定义可以在项目的任意一个模块中,但是Django中一般在views.py中定义。或者可以说每个应用的views.py
的主要功能就是创建视图。
如何创建一个视图并当用于输入url时展示在页面呢?由以下两步就可以搞定

第一步.创建视图

创建视图基本格式如下,在任意应用的views.py中:

from django.http import HttpRequest,HttpResponse
def helloword(request):
    return HttpResponse("Hello,Django!")
第二步.映射URL

创建好视图之后,需要提供一个url在浏览器中访问。首先有一个疑问:Django如何处理一个请求?
1.一般情况下,Django通过配置文件settings.py中ROOT_URLCONF配置的值来决定根URLConfig。如果请求的HttpRequest中带有urlconf属性,则会使用该urlconf。
2.Django加载根URLConfig中指定的模块中urlpatterns的值,这些值是django.urls.path()或django.urls.re_path()中的list.
3.Django依次匹配根URLConfig中每个urlpatterns,在与请求的URL匹配的第一个模式停下来.
4.一旦匹配到合适的urlpatterns,Django就会导入并且调用给定view的函数。并且传入HttpRequest作为第一个参数。
5.如果没有匹配到urlpatterns,Django会引入一个合适的错误处理视图,如404、400…
知道url匹配原理后,就可以为这个视图配置一个url了,首先寻找根URLConf,在Settings.py中:

ROOT_URLCONF = 'mysite.urls'

一般每个项目的根UrlConf默认为该项目的urls.py,因此mysite.urls.py为根URLConf,在mysite.urls.py中:

"""mysite URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path,include
from polls import views

urlpatterns = [
    path('admin/', admin.site.urls),
]

在这个文件注释中对三种方式创建url进行了说明。首先导入对应的views模块,然后在urlpatterns列表中通过path()来指定一个url,如:

from polls import views
path('hello/', views.helloword, name='helloword'),

根据匹配原理,当匹配到hello时,就会导入views并调用helloword函数,现在就可以在浏览器中访问该视图了,输入http://127.0.0.1:8000/hello.
这是使用第一种方式进行url创建的,但是并不推荐这种方式,因为如果将每个应用的url全部配置在根UrlConf中,随着项目越来越庞大,url会变得非常混乱。应该使用第三种方式,在根UrlConf中,通过include()函数来引入每个应用的UrlConf,这样当根UrlConf中匹配成功后,会通过include()在对应的应用中进行匹配。使用这种方式创建url如下:

path('hello/', include('polls.urls')),

引入了polls.urls.py,在polls.urls.py中:

from . import views
path('', views.helloword),

处理请求错误

Django中,除200外,每个响应码都有对应的一个类,这些类都是HttpResponse的子类,如:

  • HttpResponsePermanentRedirect:301
  • HttpResponseNotModified:304
  • HttpResponseBadRequest:400
  • HttpResponseNotFound:404
  • HttpResponseForbidden:403
  • HttpResponseServerError:500
    因此在请求时如果需要处理错误,返回这些HttpResponse的子类即可,如:
def get_student(requset):

    try:
        stu1 = Student.objects.get(name='Little.Hong')
    except Student.DoesNotExist:
        return HttpResponseNotFound('<h1>Page not found</h1>')
    else:
        return HttpResponse("name:{0},age:{1}".format(stu1.name, stu1.age))

此外,对于常见的404错误,除了使用HttpResponseNotFound以外,还可以抛出Http404异常进行处理:

from .models import Student, classRoom
from django.http import Http404
def get_student(requset):
    try:
        stu1 = Student.objects.get(name='Little')
    except Student.DoesNotExist:
        raise Http404("page not found")
    else:
        return HttpResponse("name:{0},age:{1}".format(stu1.name, stu1.age))

View装饰器

Django中提供了几个用于视图的装饰器函数,以支持Http请求:
修饰HTTP请求方式:
以下装饰器是django.views.decorators.http中的,用于限制view的请求方式,如果请求方式不符合条件,返回django.http.HttpResponseNotAllowed。
@require_http_methods():表示该视图只能用该方法中提供的请求方式。
@require_GET():表示该视图只能使用GET请求。
@require_POST():表示该视图只能使用POST请求。
@require_safe(): 表示该视图只能使用GET和HEAD。

view快捷工具

在django.shortcuts包中,提供了四个快捷方法,可以用于HTTP请求和响应时。

render(Request,templatename,[options args]):将view和模板进行绑定,返回一个HttpResponse。

在实际开发中,views中仅仅处理请求和响应,不应该将页面的代码也写在view中,而是将页面设计交给模板,使用该方法将view和模板进行绑定即可。
1参:request对象
2参:模板名
可选参数:
1.已dict形式传入需要传入到template的对象
2.其他参数以关键字形式传入,有context,content_type,status,using.
如:

def get_student(request):

    try:
        stu1 = Student.objects.get(name='Little.Hong')
    except Exception:
        raise Http404("page not found")
    else:
        return render(request, 'student_show.html', {'stu': stu1})
redirect():重定向。有以下几种参数:

1.redict(model):传入一个model,这种情况下,将会回调model中的get_absolute_url()方法,因此,要在传入的model中定义该方法。
2.redict(viewname):传入一个view,这种情况下,会通过reverse()方法进行反向解析得到url,还可以显式调用reverse()传入参数。
如:

# urls.py中配置url
urlpatterns = [
    path('time', views.get_date_time, name='get_date_time')
]

# views.py中定义视图
from django.shortcuts import reverse

def get_date_time(request):
    now = datetime.now()
    return HttpResponse("now:{0}".format(now))

def get_student(request):
    try:
        stu1 = Student.objects.get(name='Little.Hong')
    except Exception:
        raise Http404("page not found")
    else:
        return redirect("get_date_time")
    # or
    return redirect(reverse("get_date_time"))

3.redict(‘http://…’):直接传入一个硬编码格式的url

get_object_or_404():调用model.Manager的get()方法,如果没有指定项,抛出Http404异常,而不是model.DoesNotExist异常

在查询时,model.Manager.get()如果没有查询结果,则会出现models.DoesNotExist异常,如果使用get_object_or_404(),则没有查询结果时抛出Http404异常,如:
使用get():

def get_student(request):
    try:
       stu1 = Student.objects.get(name='Little')
    except Student.DoesNotExist:
        raise Http404("Page not found")
    return render(request, "student_show.html", {"stu": stu1})

等价于使用get_object_or_404():

def get_student(request):

    stu1 = get_object_or_404(Student, name='Little')
    return render(request, "student_show.html", {"stu": stu1})
get_list_or_404():将model.Manager的filter()结果强制转换为list,如:

def get_student(request):

    stu1 = list(Student.objects.filter(name='Little.Hong'))

等价于:

from django.shortcuts import get_list_or_404
def get_student(request):

    stu1 = get_list_or_404(Student, name='Little.Hong')

猜你喜欢

转载自blog.csdn.net/fightfightfight/article/details/80010705