Django的请求和响应

请求和响应

  1. 请求和相应

    1. django中的请求
      • 视图函数中的第一个参数即为HttpRequest对象
      • django接受到http协议的请求后,会根据请求数据报文创建HttpRequest对象
      • HttpRequest对象通过属性,描述了请求的所有相关信息
        • HttpRequest属性:
          属性名说明
          path_infoURL字符串
          method字符串,表示Http请求方法:GET、POST、PUT等
          GETQueryDict查询字典的对象,包含get请求方式的所有数据
          POSTQueryDict查询字典的对象,包含post请求方式的所有数据
          FILES类似于字典的对象,包含所有的上传文件信息
          COOKIESpython字典,包含所有的cookie,键和值都为字符串
          session类似于字典对象,表示当前的会话
          body字符串请求体的内容
          scheme请求协议(http或者https)
          request.get_full_path()请求的完整路径,会将查询字符串一并取出
          request.META请求中的元数据(消息头)
          requset.META[‘REMOTE_ADDR’]客户端IP地址
    2. django中的响应对象
      • 构造函数:
        • HttpResponse(content=响应体,content_type=响应体数据类型,status=状态码)
      • 作用:
        • 向客户端浏览器返回响应,同时携带响应体类容
      • 参数:
        • content: 表示返回的内容
        • status_code: 返回的HTTP响应状态码(默认为200)
        • content_type: 指定返回数据的MIME类型(默认为text/html),浏览器会根据这个属性来显示数据
          • 常见content_type:
            • ‘text/html’: 默认的,HTML文件
            • ‘text/plain’: 纯文本
            • ‘text/css’: css文件
            • ‘text/javascript’: js文件
            • ‘multipart/form-data’: 文件提交
            • ‘application/json’: json传输
            • ‘application/xml’: xml文件
      • HttpResponse子类
        类型作用状态码
        HttpResponseRedirect重定向302
        HttpResponseNotModified未修改304
        HttpResponseBadRequest错误请求400
        HttpResponseNotFound没有对应的资源404
        HttpResponseForbidden请求被禁止403
        HttpResponseServerError服务器错误500
  2. GET请求和POST请求

    • 定义:

      • 无论是GET还是POST,统一都由视图函数接收,通过判断request.method区分具体的请求动作

      • 样例

        if request.method == 'GET':
        处理get请求时的业务逻辑
        elif request.method == 'POST':
        处理POST请求时的业务逻辑
        else:
        处理其他请求业务的逻辑
        
    • GET处理

      • GET请求动作一般用于向服务器获取数据
      • 能够产生GET请求的场景
        • 浏览器地址栏输入URL回车后
        • <a href = “地址?参数=值&参数=值”>
        • form表单中的method为get
      • GET请求中,如果有数据需要传递给服务器,通常会用查询字符串(Query String)传递,注意不要传递敏感数据
        • URL格式:XXX?参数名1=值&参数名2=值(如:http://127.0.0.1:8000?a=100&b=200

        • 服务器端接收参数:获取客户端请求GET提交的数据方法示例

          request.GET['参数名'] #得到该参数名的值
          request.GET.get('参数名',’默认值‘) #得到该参数名的值,如果该参数名不存在则返回默认值
          request.GET.getlist(’参数名‘) #如果该参数名存在多个返回值,则用getlist来接收```
          
    • POST 处理

      • POST请求动作一般用于向服务器提交大量/隐私数据

      • 客户端通过表单等POST请求将数据传递给服务器端;如:

        <form method='post' action="/login"> #action指明post请求发给哪个路由
           姓名:<input type="text" name="username">
           <input type='submit' value='登陆'>
        </form>
        
      • 服务器端接收参数:通过request.method来判断是否为post请求

      • 使用post方式接收客户端数据

        request.POST['参数名'] #得到该参数名的值
        request.POST.get('参数名',’默认值‘) #得到该参数名的值,如果该参数名不存在则返回默认值
        request.POST.getlist(’参数名‘) #如果该参数名存在多个返回值,则用getlist来接收
        
      • 注意:发送POST请求时,django需要取消csrf验证,否则django会拒绝客户端发来的POST请求,报403响应

      • 取消csrf验证:注释掉settings.py文件中的MIDDLEWARE中的csrfviewsmiddleware的中间件

  3. Django的设计模式(MTV)

    • 设计模式:MVC和MTV
      • MVC(model-view-controller)模型-视图-控制器模式
        • M 模型层,主要用于对数据库层的封装
        • V 视图层,用于向用户展示结果
        • C 控制层,用于处理请求、获取数据、返回结果
        • 优点:降低模块间的耦合度
      • MTV (model-template-view) 模型-模版-视图模式
        • M 模型层,负责与数据库交互
        • T 模板层,负责呈现内容到浏览器(html)
        • V 视图层,负责接收请求、获取数据、返回结果
        • 优点:降低模块间的耦合度
  4. 模板层

    • 模板定义:

      • 模板是可以根据字典数据动态变化的HTML网页
      • 模板可以根据视图中传递的字典数据动态生成相应的HTML网页
    • 模板配置

      • 创建模板文件夹<项目名>/templates
      • 在settings.py中TEMPLATES配置项
        • BACKEND:指定模板的引擎
        • DIRS:模板的搜索目录,可以是一个或多个
        • APP_DIRS:是否要在子应用中的templates文件夹中搜索模板文件
        • OPTIONS:有关模板的选项
    • 配置中需修改的部分

      • 设置DIRS - ‘DIRS’:[os.path.join(BASE_DIR,‘templates’)],
    • 模板的加载方式

      • 方案一:通过loader获取模板,通过HttpResponse进行响应,在视图函数中进行如下配置:

        from django.template import loader
        t = loader.get_template("模板文件名") #通过loader加载模板,得到一个loader对象
        html = t.render(字典数据) #将t(loader对象)转换成HTML字符串
        return HttpResponse(html) #用响应对象的方式将转换的字符串内容返回给浏览器
        
      • 方案2:使用render()直接加载并响应模板,在函数视图中进行如下配置

        from django.shortcuts import render
        return render(request,'模板文件名',字典数据)
        
    • 视图层与模板层之间的交互

      • 视图函数中可以将python变量封装到字典中传递到模板;样例:

        def xxx_view(request):
           dic = {
           "变量1":"值1""变量2":"值2"}
           return render(request,'xxx.html',dic)
        
      • 在模板中,我们可以使用 {{变量名}} 的语法调用视图传进来的变量

    • 模板层-变量

      • 模板层可接收的数据类型
        类型名注释
        str字符串
        int整型
        list列表
        tuple元组
        dict字典
        func方法
        obj类实例化对象
    • 在模板中使用变量语法

      • {{ 变量名 }}
      • {{ 变量名.index }} #传入的变量为列表、元组等,可用.index方法取出其中的元素
      • {{ 变量名.key }} #传入的变量为字典,可用.key方法获取key所对应的值
      • {{ 对象.方法 }} #调用对象的方法
      • {{ 函数名 }} #调用函数
    • 模板标签

      • 作用:将一些服务器端的功能嵌入到模板中,例如流程控制等

      • 语法:

        {% 标签 %}
        …………
        {% 结束标签 %} #django中大部分标签都需要使用结束标签封口
        
      • IF标签

        • 语法

          {% if 条件表达式1 %}
          ……
          {% elif 条件表达式2 %}
          ……
          {% else %}
          ……
          {% endif %} #必须使用endif标签进行结束
          
        • 注意:

          • if条件表达式例可以用的运算符==,!=,<,>,<=,>=,in.not in,is,is not,not,and,or;
          • 在if标记中使用实际括号是无效的语法,如果需要他们指示优先级,则应使用嵌套的if标记
          • if语句中,运算符两侧不能紧挨变量或常量,必须用空格隔开
          • 关于if标签的语法参考官方文档
        • 样例

          <form action='/text' method="post">
             <input type="text" name="x" value='{{ x }}'>
             <select name="op">
                <option value="add" {%if op == 'add' %}selected{%endif%}> +</option>
                <option value="sub" {%if op == 'sub' %}selected{%endif%}> -</option>
                <option value="mul" {%if op == 'mul' %}selected{%endif%}> *</option>
                <option value="div" {%if op == 'div' %}selected{%endif%}> /</option>
             </select>
             <input type="text" name="y" value='{{ y }}'> = <span>{{ result }}</span>
             <div><input type="submit" value="开始计算">
             </div>
          </form>
          
        • for 标签

          • 语法:
             {% for 变量 in 可迭代对象 %}
             …… 循环语句
             {% empty %}
             …… 可迭代对象为空时显示的语句
             {% endfor %}
          
          • 可迭代对象的传递,从视图函数以字典形式传递给模板文件,需要保证模板文件中的可迭代对象名与视图函数中定义的键名相同 <h3>{% for i in x %}{{ forloop.counter }}this is in for {{i}} {%endfor%}</h3> # x由视图函数传入
          • 关于for标签的语法参考官方文档
        • 内置变量 - forloop

          变量描述
          forloop.counter返回当前循环的索引(从1开始索引)
          forloop.counter0返回当前循环的索引(从0开始索引)
          forloop.revcounter返回当前循环的索引(从1开始索引counter值的倒序)
          forloop.revcounter0返回当前循环的索引(从0开始索引counter值的倒序)
          forloop.first如果当前循环是第一次循环,则返回True
          forloop.last如果当前循环是最后一次循环,则返回True
          forloop.parentloop如果为嵌套循环,parentloop则表示外层循环
        • 模板过滤器

          • 定义:在变量输出时,对变量的值进行处理
          • 作用:可以通过使用过滤器来改变变量的输出显示
          • 语法:{{变量|过滤器1:‘参数值1’ | 过滤器2:‘参数值2’}}
          • 关于过滤器的语法参考官方文档
          • 常用过滤器
            过滤器说明
            lower将字符串转换为全部小写
            upper将字符串转换为全部大写
            safe禁用转义,告诉模板这个变量是安全的,可以解释执行
            add:“n”将value的值增加n
            default:“默认值”变量不存在时,返回默认值
            truncatechars:‘n’如果字符串的字符多余指定的字符数量,那么会被截断,截断的字符串将以可翻译的省略号序列("…")结尾
            forloop.parentloop如果为嵌套循环,parentloop则表示外层循环
        • 模板的继承

          • 定义:模板的继承可以使父模板的内容重用,子模板直接继承父模板的全部内容并可以覆盖父模板中相应的块

          • 语法 - 父模板中:

            • 定义父模板中的块block标签
            • 标识出哪些在子模块中是允许被修改的(block标记的继承时都是可以进行修改的)
            • block标签:在父模板中定义,可以在子模板中覆盖
          • 语法 - 子模板中:

            • 继承模板extends标签(写在模板文件的第一行)

              • 例如{% extends 'base.html '%}#继承父模板base.html
            • 子模板重写父模板中的内容块

              {% block block_name %}
              子模板块用来覆盖父模板中 block_name 块的内容
              {% endblock block_name %} #block_name可省略
              
          • 重写的覆盖规则:

            • 不重写,将按照父模板的效果显示
            • 重写,则按照重写效果显示
          • 注意:模板继承时,服务器端的动态内容无法继承,例如:视图给父模板传递的变量,在子模板中无法拿到

          • 例:

            • 父模板中

              {% block block_name %}
              
              <h4>this is in parent</h4>
              {% endblock %}
              
            • 子模板中

              {% extends 'test_html.html' %}
              {% block block_name %}
              <h3> this is in base.html </h3>
              {% endblock %}
              
  5. URL反向解析

    • URL:
      • 代码中常出现URL的位置:
        • 模板【HTML中】:
          <a href='url'>超链接</a> #点击后页面跳转至url
          <form action='URL' method='post'> #form表单中的数据用post方法提交值URL
        • 视图函数中 - 302跳转 HttpResponseRedirect(‘url’) #将用户地址栏中的地址跳转到URL
      • 代码中URL书写规范:
        • 绝对地址:http://127.0.0.1:8000/page1 (将协议、域名、端口、path全部写出)
        • 相对地址:
          1. ‘/page/1’ : '/'开头的相对地址,浏览器会把当前地址栏里的协议、IP、端口加上这个path,作为最终访问地址。如:http://127.0.0.1:8000 + /page/1
          2. ‘page/1’ : 没有’/‘开头的相对地址,浏览器会根据当前URL的最后一个’/'之前的内容加上这个path最为最终访问地址。如:http://127.0.0.1:8000/topic/detail,加上相对地址后的访问地址为:http://127.0.0.1:8000/topic/page/1
    • URL反向解析
      • 定义:URL反向解析是指在视图或模板中,用path定义的名称来动态查找或计算出相应的路由
      • 语法:
        • path(route,views,name=‘别名’)
        • 例:path(‘page’,views.page_view,name = ‘page_url’)
        • 根据path中的name关键字传参给URL确定了唯一的名字,在模板或视图中,可以通过这个名字反向推断出此URL信息
      • 模板中 - 通过URL标签实现地址的反向解析
        • {% url ‘别名’ %}

        • {% url ‘别名’ ‘参数值1’ ‘参数值2’ %},参数值1:向路由中传入的参数


        • {% url 'page1' '100' %} #解析name=page1的路由,并传入参数100
          {% url 'page2' key1='1' key2='2' %} #解析name=page2的路由,并关键字传参key1,key2 注意 路由解析时传递的参数均为字符串方式传入

        • 在视图函数中 - 通过调用django中的reverse方法进行反向解析

          from django.urls import reverse
          reverse('别名', args=[ ], kwargs={ })
          # 例 :
          reverse('page1',args=[100]) #解析name=page1的路由,并传入参数100
          reverse('page2',kwargs={key1=1,key2=2})
          
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值