web项目 day02(一)

本文围绕User功能开发展开,涵盖“用户中心”模块功能,如获取验证码、登录注册等。介绍了User模型及接口规划,分析开发难点。阐述RESTful与前后端分离概念及代码实现,还涉及第三方短信平台接入、Django缓存使用,以及Cookie、Session机制剖析与代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

User 功能开发

“⽤户中⼼” 模块功能概览

  • 获取短信验证码
  • 通过验证码登录、注册
  • 获取个⼈资料
  • 修改个⼈资料
  • 头像上传

User 模型及接⼝规划

  1. User 模型设计 (仅作参考)
FieldDescription
phonenum
nickname昵称
sex性别
birth_year出⽣年
birth_month出⽣⽉
birth_day出⽣⽇
avatar个⼈形象
location常居地
  1. 接⼝规划
  • 接⼝1: 提交⼿机号,发送短信验证码
  • 接⼝2: 提交验证码,登录注册

开发中的难点

  1. 如何向前端返回 json 数据
  2. 短信发送如何处理
  3. 验证码如何处理
  • 验证码需随机产⽣,登录注册验证码⼀般为 4~6 位随机数
  • 第⼀个接⼝获取到的验证码在登录接⼝还需要使⽤,需如何保存
  • 每个验证码都有有效期,应如何处理

RESTful 与前后端分离

一 . RESTful
  1. RESTful 最佳实践 http://www.ruanyifeml
  2. RESTful 是⼀种⽹络软件架构⻛格, ⽽⾮⽤ URL 定位⼀个⽹络资源
  3. ⽤ HTTP 动词描述对资源的操作
  • GET: 获取资源
  • POST: 新建资源
  • PUT: 更新资源
  • PATCH: 局部更新资源
  • DELETE: 删除资源
  1. 误区
  • URL 中使⽤动词

  • URL 中出现版本号
    (1) 参数⽤ querystring 表示, ⽽不要拼在 path 部错误示范: GET /user/books/foo/bar
    (2) 正确示范: GET /user/books?foo=bar

  • 状态码的使⽤要精确
    2xx:操作成功
    3xx:重定向
    4xx:客户端错误
    5xx:服务器错误

  • RESTful 与 Django REST framework 的区别

二 . 前后端分离

在这里插入图片描述
传统 Web 开发, view 函数中需要进⾏模版渲染, 逻辑处理与显示的样式均需要后端开发.

变成前后端分离后, 显示效果的处理完全交给前端来做, 前端⾃由度变⼤. 后端只需要传递前端需要
的数据即可, 将后端⼈员从繁琐的显示处理中解放出来, 专⼼处理业务逻辑

  • 优点: 前端负责显示, 后端负责逻辑, 分⼯更加明确, 彻底解放前、后端开发者
  • JSON: 完全独⽴于编程语⾔的⽂本格式, ⽤来存储和表示数据
  • 前后端分离后的开发流程

在这里插入图片描述

三. 代码实现
from json import dumps

from django.http import HttpResponse

def render_json(data=None, error_code=0):
    '''将返回值渲染为 JSON 数据'''
    result = {
        'data': data,       # 返回给前端的数据
        'code': error_code  # 状态码 (status code)
    }

    json_str = dumps(result, ensure_ascii=False, separators=[',', ':'])
    return HttpResponse(json_str)
四. 接⼝的定义
  1. 定义接⼝基本格式
{
    "code": 0,   // 错误码 (status code)
    "data": {    // 接口数据
        "user": {
            "uid": 123321,
            "username": "Lion",
            "age": 21,
            "sex": "Male"
         },
        "date": "2018-09-12",
    }
}
  1. 定义返回码
codedescription
0正常
1000服务器内部错误
1001参数错误
1002数据错误
  1. 详细定义每⼀个接⼝的各个名称 (Name)
  • 描述 (Description)
  • ⽅法 (Method)
  • 路径 (Path)
  • 参数 (Params)
  • 返回值 (Returns)
  1. 接⼝定义举例:
    接⼝名称:提交验证码登录
  • Description: 根据上⼀步的结果提交需要的数据
  • Method: POST
  • Path: /user/login
  • Params:
fieldrequiredtypedescription
phoneYesint⼿机号
codeYesint验证码
  • Return:
fieldrequiredtypedescription
uidYesint⽤户 id
nicknameYesstr⽤户名
ageYesint年龄
sexYesstr性别
locationYesstr常居地
avatarsYeslist头像 URL 列表, 最多为 6 张

示例:

{
    "code": 0,
    "data": {
        "uid": 123,                             // 用户 id
        "nickname": "Miao",                     // 用户名
        "age": 21,                              // 年龄
        "sex": "M",                             // 性别
        "location": "China/Beijing",            // 常居地
        "avatars": "http://xxx.com/icon/1.jpg"  // 头像
    },
}

第三⽅短信平台的接⼊

一 . 短信验证整体流程:
  1. ⽤户调⽤应⽤服务器 “获取验证码接⼝” (点击 “获取验证码” 按钮时触发)
  2. 应⽤服务器调⽤短信平台接⼝, 将⽤户⼿机号和验证码发送到短信平台
  3. 短信平台向⽤户发送短信
  4. ⽤户调⽤ “提交验证码接⼝”,向应⽤服务器进⾏验证
  5. 验证通过,登录、注册……
二 . 可选短信平台

阿⾥云: https://www.aliyun.com/product/sms
腾讯云: https://cloud.tencent.com/document/product/382
⽹易云: https://netease.im/sms
(大公司的注册流程比较严格,可选下面两项)
云之讯: https://www.ucpaas.com/
互亿⽆线: http://www.ihuyi.com/

三 . 注册账号后, 将平台分配的 APP_ID 和 APP_SECRET 添加到配置中

APP_ID: 平台分配的 ID
APP_SECRET: 与平台交互时, ⽤来做安全验证的⼀段加密⽤的⽂本, 不能泄漏给其他⼈

四 . 注册平台的短信模版
五 . 按照平台接⼝⽂档开发接⼝

短信平台的接⼝通常是 HTTP 或 HTTPS 协议, 接⼊的时候只需按照接⼝格式发送 HTTP 请求
即可
接⼝的返回值⼀般为 json 格式,收到返回结果后需要解析

Django 中的缓存

  1. 接⼝及⽤法
from django.core.cache import cache
# 在缓存中设置 age = 123, 10秒过期
cache.set('age', 123, 10)
# 获取 age
a = cache.get('age')
print(a)
# ⾃增
x = cache.incr('age')
print(x)
  1. 使⽤ Redis 做缓存后端

安装

 pip install django-redis

settings 配置

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/0",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "PICKLE_VERSION": -1,
        }
    }
}
  1. 利⽤过期时间可以处理⼀些定时失效的临时数据, ⽐如⼿机验证码

Cookie、 Session 机制剖析

一 . 产⽣过程
  1. 浏览器: 向服务器发送请求
  2. 服务器: 接受并创建 session 对象 (该对象包含⼀个 session_id)
  3. 服务器: 执⾏ views 函数, 并得到⼀个 response 对象
  4. 服务器: 执⾏ response.set_cookie(‘sessionid’, session_id) 将 session_id 写⼊ cookie
  5. 服务器: 将 response 传回浏览器
  6. 浏览器: 读取 response 报⽂, 从 Cookies 取出 session_id 并保存
二 . 后续请求
  1. 浏览器: 向服务器发送请求, session_id 随 Cookies ⼀同发给 Server
  2. 服务器: 从 Headers 的 Cookies 中取出 session_id
  3. 服务器: 根据 session_id 找出对应的数据, 确认客户端身份
三 . Django 中的代码实现
class SessionMiddleware(MiddlewareMixin):
    def __init__(self, get_response=None):
        self.get_response = get_response
        engine = import_module(settings.SESSION_ENGINE)
        self.SessionStore = engine.SessionStore  # 设置 Session 存储类

    def process_request(self, request):
        # 从 Cookie 获取 sessionid
        session_key = request.COOKIES.get('session_id')

        # 通过 session_key 获取之前保存的数据
        request.session = self.SessionStore(session_key)

    def process_response(self, request, response):
        try:
            # View 函数结束后, 获取 session 状态
            accessed = request.session.accessed
            modified = request.session.modified
            empty = request.session.is_empty()
        except AttributeError:
            pass
        else:
            # 如果 Cookie 中有 sessionid, 但 session 为空,
            # 说明 view 中执行过 session.flush 等操作,
            # 直接删除 Cookie 中的 session
            if 'session_id' in request.COOKIES and empty:
                response.delete_cookie(
                    settings.SESSION_COOKIE_NAME,
                    path=settings.SESSION_COOKIE_PATH,
                    domain=settings.SESSION_COOKIE_DOMAIN,
                )
            else:
                if accessed:
                    patch_vary_headers(response, ('Cookie',))
                if (modified or settings.SESSION_SAVE_EVERY_REQUEST) and not empty:
                    # 设置过期时间
                    if request.session.get_expire_at_browser_close():
                        max_age = None
                        expires = None
                    else:
                        max_age = request.session.get_expiry_age()
                        expires_time = time.time() + max_age
                        expires = cookie_date(expires_time)

                    # 保存会话数据, 并刷新客户端 Cookie
                    if response.status_code != 500:
                        try:
                            request.session.save()
                        except UpdateError:
                            raise SuspiciousOperation(
                                "The request's session was deleted before the "
                                "request completed. The user may have logged "
                                "out in a concurrent request, for example."
                            )

                        # 让客户端将 sessionid 添加到 Cookie 中
                        response.set_cookie(
                            'session_id',
                            request.session.session_key,
                            max_age=max_age,
                            expires=expires,
                            domain=settings.SESSION_COOKIE_DOMAIN,
                            path=settings.SESSION_COOKIE_PATH,
                            secure=settings.SESSION_COOKIE_SECURE or None,
                            httponly=settings.SESSION_COOKIE_HTTPONLY or None,
                        )
        return response
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值