# WEB后端服务第16天-Django第六天

WEB后端服务第16天-Django第6天

一、请求与响应详解

1.1 request对象

1.1.1 扩展:mysql连接配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'advance1',
        'HOST': '119.3.26.17',
        'PORT': 3306,
        'USER': 'root',
        'PASSWORD': 'root',
        'CHARSET': 'utf8'
    }
}

默认情况下,需要安装mysqlclient, 我们也可以安装pymysql,但需要在主目录下要进行初始化安装。主工程目录下的_init_.py脚本中的内容:

import pymysql

pymysql.install_as_MySQLdb()
1.1.2 请求对象中的QueryDict属性
  • GET 查询参数

  • POST 表单参数, 包含post请求方法的参数

  • COOKIES 客户端中的当前domain的所有的Cookie信息

  • META wsgi中请求元信息(服务器环境信息、客户端请求信息)== environ

    • REMOTE_ADDR 客户端IP地址
    • PATH_INFO 请求路径
    • REQUEST_METHOD 请求方法
    • QUERY_STRING 查询参数
    • CONTENT_TYPE 上传数据类型
  • FILES 上传的表单参数中所有的文件对象, MultiValueDict类对象, 文件对象的类型是InMemoryUploadedFile

  • session 会话中存储的数据(可以跨多个请求)

GET请求的案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Regist2</title>
</head>
<body>
<p>
<form method="get" enctype="application/x-www-form-urlencoded">
        <input name="name" placeholder="username">
        <br>
        <input name="phone" placeholder="phone">
        <br>
        爱好:
        {% for love in loves %}
            <input type="checkbox" name="love" value="{{ love }}"> {{ love }}
        {% endfor %}
        <br>
        <button>提交</button>
</form>
</p>
<p>
    GET请求的查询参数<br>
    <ul>
    {% for key, value in request.GET.items %}
        {% ifnotequal key 'love' %}
            <li>{{ key }}: {{ value }}</li>
        {% endifnotequal %}
    {% endfor %}
    <li>
        爱好:
        {% for item in select_loves %}
            {{ item }},
        {% endfor %}
    </li>
</ul>
</p>

</body>
</html>
# Create your views here.
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def regist(request, user_id=None):
    loves = ['H5', 'Java', 'Python', 'Linux', 'Oracle', 'Cookie']
    # 获取参数名相同的多个参数值
    select_loves = request.GET.getlist('love')
    return render(request, 'regist2.html', locals())

POST/PUT-ajax请求案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Regist3</title>
</head>
<body>
<p>
<form method="post" enctype="application/x-www-form-urlencoded">
    <input name="name" placeholder="username">
    <br>
    <input name="phone" placeholder="phone">
    <br>
    <button>提交</button>
</form>
</p>

<p>
    <button onclick="up_ajax()">ajax发起put请求</button>
    <script>
        function up_ajax() {
            data = {
                name: '李成',
                phone: '1991828272',
                loves: ['唱', '跳', 'RAP', '篮球']
            };
            fetch('', {
                method: 'PUT',
                body: document.forms[0].serialize,
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                }
            }).then(response => response.text())
                .then(html => {
                    document.write(html)
                })
        }
    </script>
</p>
<p>
    POST请求参数:
<ul>
    {% for key, value in request.POST.items %}
        <li>{{ key }}: {{ value }}</li>
    {% endfor %}
</ul>
</p>
<p>
    PUT的参数(body): {{ request.body }}
    <br>
    Content-Type:  {{ request.content_type }};{{ request.encoding }}

</p>

</body>
</html>
@csrf_exempt
def regist(request, user_id=None):
    print(request.POST)
    print(request.method)
    return render(request, 'regist3.html', locals())

POST实现文件上传案例


1.1.3 请求对象中的普通信息
  • path 请求路径
  • method 请求方法, GET/POST/PUT/DELETE
  • content_type 数据类型, 如 请求头的Content-Type: text/html;charset=utf-8 , content_type只接数据类型 text/html。charset=utf-8的部分编码则由encoding存储
  • encoding 数据编码,
  • body 字节码数据, 一般接收上传的json数据, put上传的数据可以使用body来获取。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Regist</title>
</head>
<body>
<p>
<form method="post" enctype="application/x-www-form-urlencoded">
        <input name="name" placeholder="username">
        <br>
        <input name="phone" placeholder="phone">
        <br>
        <input type="password" name="password" placeholder="password">
        <br>
        <input type="date" placeholder="生日">
        <br>
        <button>提交</button>
</form>
</p>
<p>
    <button onclick="up_ajax()">ajax上传json数据</button>
    <script>
        function up_ajax() {
            data = {
                name: document.forms[0].name.value,
                phone: document.forms[0].phone.value
            };
            fetch('', {
                method: 'POST',
                body: JSON.stringify(data),
                headers: {
                    'Content-Type': 'application/json;charset=utf-8'
                }
            }).then(response => response.text())
            .then(text =>{
                document.write(text)
            });
        }
    </script>
</p>
<p>
    请求路径-path: {{ request.path }}
    <br>
    请求的URI(统一资源标识符): {{ request.get_raw_uri }}
<pre>
            URL : 统一资源定位符, 资源的网络地址
            URI:  统一资源标识符, 用于RESTful规范中,可以理解为URL
        </pre>
</p>
<p>
    请求方法: {{ request.method }}
    <br>
    content_type: {{ request.content_type }}
    <br>
    encoding: {{ request.encoding }}
    <br>
    content_params: {{ request.content_params }}
</p>
<p>
    body: {{ request.body }}
</p>
</body>
</html>

github 仓库: git@github.com:disenQF/advanceDjango1.git

1.2 response对象

响应对象是视图函数返回的对象。由我们自己创建,当然,django很多快捷方法,如render()/redirect()快速生成response响应对象。

常用的响应类:

  • HttpResponse
  • HttpResponseRedirect
  • JsonResponse

响应对象中包含的属性:

  • content :响应的内容
    • 如果是HttpResponse对象,则content可以是字节码也可以是字符串
    • JsonResponse ,则content可以是dict字典
  • status 响应的状态码
  • content_type:响应的数据类型

设置响应头header

直接通过响应对象的字典特性来设置, 如 response[‘Content-Type’] = ‘image/jpeg’。

二、会话技术详解

一次会话(Session)或连接从浏览器的一个Request开始, 到服务器返回Response结束。可以在多个页面需要传递部分数据。

Django的Session的数据默认存储在django_session表中。但Session依赖于Cookie技术。客户端如果禁用了Cookie,则Session也会失效。

2.1 Cookie

def add_cookie(request):
    # 生成token,并存储到 Cookie中
    token = uuid.uuid4().hex

    resp = HttpResponse('增加Cookie: token成功')

    from datetime import datetime, timedelta
    resp.set_cookie('token', token,
                    expires=datetime.now()+timedelta(minutes=2))

    return resp

2.2 Session

def new_code(request):
    # 生成手机验证码
    # 随机产生验证码 : 大小写字母+数字
    code_txt = 'Xab9'

    phone = request.GET.get('phone')
    # 保存到session中
    request.session['code'] = code_txt
    request.session['phone'] = phone

    # 向手机发送验证码:  华为云、阿里云:短信服务

    return HttpResponse('已向 %s 手机发送了验证码!' % phone)

2.3 Token

使用UUID产生。

def login(request):
    phone = request.GET.get('phone')
    code = request.GET.get('code')

    if all((
        phone == request.session.get('phone'),
        code == request.session.get('code')
    )):
        resp = HttpResponse('登录成功')
        token = uuid.uuid4().hex  # 保存到缓存
        resp.set_cookie('token', token)

        return resp

    return HttpResponse('登录失败,请确认phone和code!')

三、静态资源

  • 绝对路径 【不推荐】
<link rel='sheetstyle' href='/static/css/my.css'>
  • 相对路径
{% load static %}
<link rel='sheetstyle' href='{% static 'css/my.css' %}>

四、验证码

  • 图片验证码

  • 短信验证码

  • 邮箱验证码

五、分页器

from django.core.paginator import Paginator,Page

def list(request):
		# 获取页号
		page_num = int(request.GET.get('page', 1))
    
    # 获取查询条件
    kw = request.GET.get(kw)
		
    # 查询数据
    datas = UserEntity.objext.filter(name__contains=kw).all()
    
    paginator = Paginator(datas, 20)
    
    pager = paginator.page(page_num)
    
    return render(request, 'list.html', locals())
<form method='get'>
    <input type='text' name='kw'  value='{{ kw }}' >
  	<button>搜索</button>
</form>
<ul>
  {% for u in pager.object_list %}
  		<li> {{u.name }} </li>
  {% endfor %}
</ul>
<div id='page'>
  	{% for p in paginator.page_range %}
  		  <span><a href="/list/?page={{ page }}&kw={{ kw }}">{{ p }}</a></span>
  	{% endfor %}
</div>

六、作业

1. 练习课堂代码并总结核心技术点

2. 实现注册登录功能

业务描述: 实现手机号登录,模拟发送短信验证码,如果手机号已存在,直接验证短信码,如果不存在,则先创建此用户,然后再验证,如果验证成功,则生成token,并保存到redis中(token:user_id)。

要求:

  • 前后端的数据格式是json
  • 提供完善信息接口, 接口参数必须提供token

3. 实现搜索功能

业务描述: 根据搜索关键字,模糊匹配商品名、类型名、商品描述,对查询的数据进行分页。

思考: 如果数据量超级多时,如何优化分页器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Django REST Framework (DRF) 是一套用于构建高效、功能丰富的 API 的 Python 框架。它是基于 Django Web 应用框架的一个独立组件,并提供了一系列工具和服务,旨在简化 API 开发过程。 ### 功能特点: #### 简化 API 创建: - DRF 提供了一套完整的、易于使用的 API 创建工具,包括认证、权限控制、序列化和分页等功能。 - 可以快速生成 CRUD(创建、读取、更新、删除)操作所需的视图和序列化器,降低了开发成本和提高了开发效率。 #### 高度自定义性: - DRF 允许开发者高度定制 API 行为,包括路由配置、错误处理、响应渲染等。 - 支持多种验证机制和权限系统,使得安全性得到保障。 #### 易于集成: - 它可以与 Django 无缝集成,也可以作为一个独立项目与其他框架配合工作,如 Flask 或 FastAPI。 - 提供了丰富的文档和示例,便于学习和使用。 #### 强大的功能集: - **模型绑定**:自动将数据模型映射到 API 资源上,简化数据管理。 - **序列化与反序列化**:强大的序列化能力允许轻松转换数据格式,并支持 JSON、XML 等多种格式。 - **动态路由**:可以根据需要动态生成和修改路由,增加灵活性。 - **过滤与排序**:提供丰富的方式对查询结果进行过滤和排序,提升用户体验。 ### 示例使用场景: - 开发需要大量数据交互的应用程序,例如电子商务平台、社交媒体应用、企业管理系统等,特别是当需要对外提供 RESTful 格式的 API 接口时。 ### 相关问题: 1. Django REST Framework 与其他后端框架相比有何优势? 2. 如何开始使用 Django REST Framework 开发自己的 API? 3. Django REST Framework 中如何实现更复杂的数据处理逻辑?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值