zoukankan      html  css  js  c++  java
  • Django(十一)视图详解:基本使用、登录实例、HttpReqeust对象、HttpResponse对象

    一、视图(基于类的视图)

    【参考】https://docs.djangoproject.com/zh-hans/3.0/topics/class-based-views/intro/

    1)视图的功能

    1. 接收请求,进行处理,与M和T进行交互,返回应答。
    2. 返回html内容 HttpResponse,也可能重定向 redirect,还可以返回json数据。

    2)视图函数使用

    二、使用

    1. 定义视图函数

    • request参数必须有。
    • 是一个HttpRequest类型的对象。
    • 参数名可以变化,但不要更改。

    2. 配置url

    • 建立url和视图函数之间的对应关系。

    2.2 url配置的过程

    1. 在项目的urls文件中包含具体应用的urls文件,在具体应用的urls文件中包含具体url和视图的对应关系。
    2. url配置项是定义在一个名叫urlpatterns的列表中,其中的每一个元素就是一个配置项,每一个配置项都调用url函数。

    3. url匹配的过程

    在这里插入图片描述
    url:http://127.0.0.1:8000/aindex?a=1

    1. 去除域名和后面的参数,剩下/aindex,再把前面的/去掉,剩下aindex
    2. 拿aindex先到项目的url.py文件中进行从上到下的匹配,匹配成功之后执行后面对应的处理动作,就是把匹配成功的部分a字符去除,然后拿剩下的部分index到应用的urls.py文件中再进行从上到下的匹配。
    3. 如果匹配成功则调用相应的视图产生内容返回给客户端。如果匹配失败则产生404错误。

    4.错误视图

    1. 404:找不到页面,关闭调试模式之后,默认会显示一个标准的错误页面,如果要显示自定义的页面,则需要的templates目录下面自定义一个404.html文件。
      • a)url没有配置
      • b)url配置错误
    2. 500: 服务器端的错误。
      • a)视图出错,即views.py页面的对应函数内部出错会显示500错误。
    3. 网站开发完成需要关闭调试模式,在settings.py文件中:
    DEBUG=False
    ALLOWED_HOST=['*']
    
    1. 显示效果:Not Found
      The requested resource was not found on this server.
    2. 自定义错误页面:建立【templates/404.html】 即可,django会自动调用此页面,不需自己调用
      系统提供:{{ request_path }} 用于返回用户请求的path
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>404错误页面</title>
    </head>
    <body>
    <h1>页面找不到:--{{ request_path }}</h1>
    </body>
    </html>
    
    1. 自定义500错误页:建立【templates/500.html】 即可
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>500错误页面</title>
    </head>
    <body>
    <h1>服务器错误</h1>
    </body>
    </html>
    

    5.捕获url参数

    • 进行url匹配时,把所需要的捕获的部分设置成一个正则表达式组,这样django框架就会自动把匹配成功后相应组的内容作为参数传递给视图函数。
      • 1)位置参数:参数名可以随意指定
      • 2)关键字参数:在位置参数的基础上给正则表达式组命名即可。
    ?P<组名>
    

    1)加带参数的链接/templates/app1/book.html

    【1】通过href属性,把book的id做为参数传给详情页,进而查询对应英雄信息

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>书籍页面</title>
    </head>
    <body>
    本站的图书有:
    <ul>
        {% for book in books %}
    		<!--【1】通过href属性,把book的id做为参数传给详情页,进而查询对应英雄信息-->
       		<li><a href="/detail/{{book.id}}"> {{book.btitle}}</a>:{{book.bpub_date}}</li>
        {%empty%}
        	暂时没有图书!!!
        {% endfor %}
    </ul>
    </body>
    </html>
    
    

    2)接收参数,渲染到模板app1/views.py

    【00】bookId为接收urls.py必须中指定的参数,来源页templates/app1/book.html
    【1】查询主键为url中传过来的参数Id。或写成:id=bookId
    【2】关联查询:查询对应书的所有英雄信息
    【3】把参数渲染到detail页面去

    from django.shortcuts import render
    from app1.models import BookInfo #【0】从模型下导入bookinfo数据模型
    
    def index(request):
        '''app1应用:首页'''
        context={} #定义1个字典
        context['hello']='hello world!!!' #向字典写一个键:值(hello:'hello world!!')
        context['wa']='wawawawawahahahaha!'
        context['list']=list(range(1,10)) #定义一个字典值为一个列表,list为把内容转换为列表
        return render(request,'app1/index.html',context) #返回:把context渲染到app1/index.html的模板文件
    
    def books(request):
        '''app1应用:图书列表页'''
        books=BookInfo.objects.all()#从数据库获取图书对象列表
        return render(request,'app1/book.html',{'books':books})#把获取到的图书对象赋值给books键。【注意】键'books'必须要加引号
    
    def detail(request,bookId):# 【00】bookId为接收urls.py必须中指定的参数,来源页templates/app1/book.html
        '''app1应用:图书详情页,显示英雄信息'''
        book=BookInfo.objects.get(pk=bookId) #【1】查询主键为url中传过来的参数Id。或写成:id=bookId
        heros=book.heroinfo_set.all() #【2】关联查询:查询对应书的所有英雄信息
        return render(request,'app1/detail.html',{'book':book,'heros':heros}) #【3】把参数渲染到detail页面去
    
    

    3)app1/urls.py配置

    【书详情页】通过url接收参数2种写法以下两种都可:
    【1.关键字参数】参数用尖括号包起来<>path(r"detail/<int:bookId>",views.detail)(视图接收参数必须与此处保持一致,即 bookId)
    【2.正则参数】参数必须要带括号re_path(r"^detail/(d+)",views.detail)

    from django.urls import path,re_path
    from . import views
    
    urlpatterns=[
        path('app1/',views.index),
        path('books/',views.books),
    
        # 【书详情页】,通过url接收参数2种写法以下两种都可:
        # path(r"detail/<int:bookId>",views.detail), #【尖括号】参数用尖括号包起来<>
        re_path(r"^detail/(d+)",views.detail), #【正则】参数必须要带括号
    ]
    

    6.普通登录案例( HttpRequest和 HttpResponse对象的API django.http)

    【参考】https://docs.djangoproject.com/zh-hans/3.0/ref/request-response/

    0)知识点:views.py视图函数的request.POST、request.GET

    1. request.POST 保存的是post方式提交的参数 QueryDict
    2. request.GET 保存是get方式提交的参数
    3. 它俩的类型 print(request.POST/GET) 返回 QueryDict类型
    4. QueryDict的传参数方式、调用方式1、调用方式2、
    5. 调用不存在的值、传入类似列表值、类似列表值调用。
    >>> from django.http.request import QueryDict #引入模块
    
    >>> q=QueryDict('a=1&b=2&c=3') #传参形式
    >>> q['a'] #调用方式1
    '1'
    >>> q.get('a') #调用方式2
    '1'
    >>> q.get('d') #调用不存在的值,什么都不返回
    >>> q.get('d','default') #设置调用不存在的值,返回一个默认的值
    'default'
    
    >>> q['d'] #调用方式1调用不存在的值,会直接报错,因此,使用调用方式一get会比较好
    
    '''
    Traceback (most recent call last):
      File "C:UsersAdministratorAppDataLocalProgramsPythonPython37libsite-p
    ackagesdjangoutilsdatastructures.py", line 76, in __getitem__
        list_ = super().__getitem__(key)
    KeyError: 'd'
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "<console>", line 1, in <module>
      File "C:UsersAdministratorAppDataLocalProgramsPythonPython37libsite-p
    ackagesdjangoutilsdatastructures.py", line 78, in __getitem__
        raise MultiValueDictKeyError(key)
    django.utils.datastructures.MultiValueDictKeyError: 'd'
    '''
    
    >>> q2=QueryDict('a=1&a=2&a=3') #传入类似列表值、及调用
    >>> q2['a']
    '3'
    >>> q2.get('a')
    '3'
    >>> q2.getlist('a')
    ['1', '2', '3']
    

    1)显示出登录页面

    参考:https://docs.djangoproject.com/zh-hans/3.0/topics/forms/

    1. 设计url,通过浏览器访问 http://127.0.0.1:8000/login 时显示登录页面。
    2. 设计url对应的视图函数login。
    3. 编写模板文件login.html。
    url 视图 模板文件
    /login login login.html

    2)登录校验功能

    1. 设计url,点击登录页的登录按钮发起请求http://127.0.0.1:8000/login_check时进行登录校验。
    2. 设计url对应的视图函数login_check:
      • 接收表单提交过来的数据。
      • 进行登录校验,若用户名密码正确则跳转到登录成功页。若失败在跳转到登录页面。
    3. 登录成功后跳转到首页。
    url 视图 模板文件
    /login_check login_check

    第1步,app1/views.py编写登陆函数、校验函数

    from django.shortcuts import render,redirect #引入重定向简写模块
    
    def login(request):
        '''登录页'''
        return render(request,'app1/login.html')
    
    def login_check(request):
        '''登录校验'''
        username=request.POST.get('username') #对应模板的input的name选项
        password=request.POST.get('password')
        if username=='jim' and password=='123':
            return redirect('/books')
        else:
            return redirect('/login')
    

    第2步,登录页面模板templates/app1/login.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>登录页面</title>
    </head>
    <body>
    POST:提交的参数请求头。数据安全性要求比较高的时候使用post.<br/>
    GET:提交的参数在url中。<br/>
    <form method="post" action="/login_check"> <!--action提交页面-->
        用户名:<input type="text" name="username" value="{{ username }}"><br/>
        密码:<input type="password" name="password"><br/>
        <input type="submit" value="登录">
    </form>
    </body>
    </html>
    

    第3步,app1/urls.py设置

    【登录页】
    【登录检测】

    from django.urls import path,re_path
    from . import views
    
    urlpatterns=[
        path('login/',views.login),#【登录页】
        path('login_check',views.login_check),#【登录检测】
    
        path('app1/',views.index),
        path('books/',views.books),
    
        # 书详情页,通过url接收参数2种写法以下两种都可:
        # path(r"detail/<int:bookId>",views.detail), #参数用尖括号包起来<>
        re_path(r"^detail/(d+)",views.detail), #参数必须要带括号
    
        path('addInfo/',views.addInfo), #添加三国书
    
        path(r'delete/<int:bid>',views.deleteInfo), #删除对应图书
    
        path(r'areas/',views.areas), #展示对应省市区信息
    ]
    
    

    第4步,把project1/settings.py

    把MIDDLEWARE 的 csrf注释掉,否则将无法实现登录。

    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        #'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]
    

    第5步,启动项目进入项目目录

    py manage.py runserver
    

    效果 http://127.0.0.1:8000/login/

    输入jim 123即跳转到 books/页面,否则跳转回登录页面。
    在这里插入图片描述

    扩展:获取请求的方式是get还是post,/app1/views.py

    print(request.method)
    

    HttpReqeust对象

    • 服务器接收到http协议的请求后,会根据报文创建HttpRequest对象,这个对象不需要我们创建,直接使用服务器构造好的对象就可以。视图的第一个参数必须是HttpRequest对象,在django.http模块中定义了HttpRequest对象的API。

    属性

    下面除非特别说明,属性都是只读的。

    • path:一个字符串,表示请求的页面的完整路径,不包含域名和参数部分。
    • method:一个字符串,表示请求使用的HTTP方法,常用值包括:'GET'、'POST'。
      在浏览器中给出地址发出请求采用get方式,如超链接。
      在浏览器中点击表单的提交按钮发起请求,如果表单的method设置为post则为post请求。
    • encoding:一个字符串,表示提交的数据的编码方式。
      如果为None则表示使用浏览器的默认设置,一般为utf-8。
      这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值。
    • GET:QueryDict类型对象,类似于字典,包含get请求方式的所有参数。
    • POST:QueryDict类型对象,类似于字典,包含post请求方式的所有参数。
    • FILES:一个类似于字典的对象,包含所有的上传文件。
    • COOKIES:一个标准的Python字典,包含所有的cookie,键和值都为字符串。
    • session:一个既可读又可写的类似于字典的对象,表示当前的会话,只有当Django 启用会话的支持时才可用,详细内容见"状态保持"。

    运行服务器,在浏览器中浏览首页,可以在浏览器“开发者工具”中看到请求信息如下图:
    在这里插入图片描述

    示例

    • 接下来演示属性path、method、encoding,对于GET、POST、FILES、COOKIES、session后面会有详细讲解。

    • path、encoding

    1)打开booktest/views.py文件,代码如下:

    def index(request):
        str='%s,%s'%(request.path,request.encoding)
        return render(request, 'booktest/index.html', {'str':str})
    

    2)在templates/booktest/下创建index.html文件,代码如下:

    <html>
    <head>
        <title>首页</title>
    </head>
    <body>
    1. request对象的path,encoding属性:<br/>
    {{ str }}
    <br/>
    </body>
    </html>
    

    2)打开浏览器请求,运行效果如下图:
    在这里插入图片描述
    3)以chrome浏览器为例,设置编码如下图,默认为utf-8编码。
    在这里插入图片描述

    method

    1)打开booktest/views.py文件,编写视图method_show,代码如下:

    def method_show(request):
        return HttpResponse(request.method)
    

    2)打开booktest/urls.py文件,新增配置如下:

      url(r'^method_show/$', views.method_show),
    

    3)修改templates/booktest/下创建index.html文件,添加代码如下:

    <html>
    <head>
        <title>首页</title>
    </head>
    <body>
    ...
    ...
    2.request对象的method属性:<br/>
    <a href='/method_show/'>get方式</a><br/>
    <form method="post" action="/method_show/">
        <input type="submit" value="post方式">
    </form>
    <br/>
    </body>
    </html>
    

    4)打开浏览器,输入如下网址:
    http://127.0.0.1:8000/
    5)浏览效果如下图:
    在这里插入图片描述
    6)点击链接,转到method_show,浏览效果如下图:
    在这里插入图片描述
    7) 回到method_test页面,点击按钮,转到method_post,浏览效果如下图,报错了。
    在这里插入图片描述
    9)回到浏览器中刷新,浏览效果如下图,点击“继续”按钮。
    在这里插入图片描述
    10)最终浏览效果如下图:

    在这里插入图片描述

    HttpResponse对象

    视图在接收请求并处理后,必须返回HttpResponse对象或子对象。在django.http模块中定义了HttpResponse对象的API。HttpRequest对象由Django创建,HttpResponse对象由开发人员创建。

    运行服务器,在浏览器中浏览首页,可以在浏览器“开发者工具”中看到响应信息如下图:
    在这里插入图片描述

    属性

    • content:表示返回的内容。
    • charset:表示response采用的编码字符集,默认为utf-8。
    • status_code:返回的HTTP响应状态码。
    • content-type:指定返回数据的的MIME类型,默认为'text/html'。

    方法

    • _init_:创建HttpResponse对象后完成返回内容的初始化。
    • set_cookie:设置Cookie信息。
    • set_cookie(key, value='', max_age=None, expires=None)
    • cookie是网站以键值对格式存储在浏览器中的一段纯文本信息,用于实现用户跟踪。
    • max_age是一个整数,表示在指定秒数后过期。
    • expires是一个datetime或timedelta对象,会话将在这个指定的日期/时间过期。
    • max_age与expires二选一。
      如果不指定过期时间,在关闭浏览器时cookie会过期。
    • delete_cookie(key):删除指定的key的Cookie,如果key不存在则什么也不发生。
    • write:向响应体中写数据。

    实例

    直接返回数据

    1)打开booktest/views.py文件,定义视图index2如下:

    def index2(request):
        str='<h1>hello world</h1>'
        return HttpResponse(str)
    

    2)打开booktest/urls.py文件,配置url。

    url(r'^index2/$',views.index2),
    

    3)运行服务器,在浏览器中打开如下网址。

    http://127.0.0.1:8000/index2/
    

    在这里插入图片描述
    如果使用这种方式构造一个漂亮丰富的页面,对于开发人员真是会发疯,于是就有了下面的方式:

    调用模板

    可以将html、css、js定义到一个html文件中,然后由视图来调用。

    1)打开booktest/views.py文件,定义视图index3如下:

    from django.template import RequestContext, loader
    ...
    def index3(request):
        #加载模板
        t1=loader.get_template('booktest/index3.html')
        #构造上下文
        context=RequestContext(request,{'h1':'hello'})
        #使用上下文渲染模板,生成字符串后返回响应对象
        return HttpResponse(t1.render(context))
    

    2)打开booktest/urls.py文件,配置url。

     url(r'^index3/$',views.index3),
    

    3)在templates/booktest/目录下创建index3.html,代码如下:

    <html>
    <head>
        <title>使用模板</title>
    </head>
    <body>
    <h1>{{h1}}</h1>
    </body>
    </html>
    

    4)运行服务器,在浏览器中打开如下网址。

    http://127.0.0.1:8000/index3/
    运行效果如下图:
    在这里插入图片描述

    调用模板简写函数render

    每次调用模板时都要执行加载、上下文、渲染三个步骤,为了简化操作,Django定义了render()函数封装了以上三个步骤的代码,定义在django.shortcuts模块中。

    1)打开booktest/views.py文件,定义视图index3如下:

    from django.shortcuts import render
    ...
    def index3(request):
        return render(request, 'booktest/index3.html', {'h1': 'hello'})
    

    是不是用render()函数调用模板比上面简单多了?

  • 相关阅读:
    获取当前具有输入焦点控件的窗口句柄
    C++日志
    IsWindowVisible
    fedora20 播放aiv视频
    nginx 伪静态大于10个参数 $10
    fedora 安装nginx+php+mysql
    限制图片目录有文件的执行权限
    jQuery制作go to top按钮
    centos 6.5 安装阿里云的一键安装包(nginx+php5.4+mysql5.1)
    centos 6.5网卡dhcp不能获得网关
  • 原文地址:https://www.cnblogs.com/chenxi188/p/12176687.html
Copyright © 2011-2022 走看看