美文网首页
DRF项目逻辑收录(一)

DRF项目逻辑收录(一)

作者: battleMonkey | 来源:发表于2019-03-28 08:12 被阅读0次

    1. app子应用 收录在 同一个文件夹

    实现

    # setting.py
    import os
    import sys
    
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
    # 配置sys.path python的系统环境变量, 让django首先搜索 apps这个包路径下的文件
    sys.path.insert(0,os.path.join(BASE_DIR,'apps'))
    
    ...
    
    # 注册子应用
    INSTALLED_APPS = [
        ...
        'rest_framework',
    ]
    

    2. redis 的配置和使用

    CACHES = {
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://127.0.0.1:6379/0",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
            }
        },
        "session": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://127.0.0.1:6379/1",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
            }
        },
    }
    
    # 设置 Django 的 session 使用  redis 引擎 存储
    SESSION_ENGINE = "django.contrib.sessions.backends.cache"
    
    # 使用名为'session'的redis-1 库 存储 session信息
    SESSION_CACHE_ALIAS = "session"
    

    3. 日志设置

    复制代码到setting下即可:

    # setting.py
    # 设置一个相对复杂的 日志配置 模板
    
    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'verbose': {
                'format': '%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s'
            },
            'simple': {
                'format': '%(levelname)s %(module)s %(lineno)d %(message)s'
            },
        },
        'filters': {
            'require_debug_true': {
                '()': 'django.utils.log.RequireDebugTrue',
            },
        },
        'handlers': {
            'console': {
                'level': 'DEBUG',
                'filters': ['require_debug_true'],
                'class': 'logging.StreamHandler',
                'formatter': 'simple'
            },
            'file': {
                'level': 'INFO',
                'class': 'logging.handlers.RotatingFileHandler',
                'filename': os.path.join(BASE_DIR, "logs/meiduo.log"),  # 日志文件的位置
                'maxBytes': 300 * 1024 * 1024,
                'backupCount': 10,
                'formatter': 'verbose'
            },
        },
        'loggers': {
            'django': {  # 定义了一个名为django的日志器
                'handlers': ['console', 'file'],
                'propagate': True,
            },
        }
    } 
    
    • 之后的收尾工作(不做会有问题呦!)
    1. 记得在 项目 目录下, 新建logs文件夹, 存放日志文件
    2. 修改 .gitignore 添加"logs/*"
    3. 创建logs/.gitkeep , 保证 可以git push 上传 空文件夹

    4. 异常处理

    1) 新建utils/exceptions.py

    处理, 数据库 读取、写入失败的问题

    # utils/exceptions.py
    
    from rest_framework.views import exception_handler as drf_exception_handler
    import logging
    from django.db import DatabaseError
    from redis.exceptions import RedisError
    from rest_framework.response import Response
    from rest_framework import status
    
    # 获取在配置文件中定义的logger,用来记录日志
    logger = logging.getLogger('meiduo')
    
    def exception_handler(exc, context):
        """
        自定义异常处理
        :param exc: 异常
        :param context: 抛出异常的上下文
        :return: Response响应对象
        """
        # 调用drf框架原生的异常处理方法
        response = drf_exception_handler(exc, context)
    
        if response is None:
            view = context['view']
            if isinstance(exc, DatabaseError) or isinstance(exc, RedisError):
                # 数据库异常
                logger.error('[%s] %s' % (view, exc))
                response = Response({'message': '服务器内部错误'}, status=status.HTTP_507_INSUFFICIENT_STORAGE)
    
        return response
    
    2) 修改 setting.py, 调用 此 异常处理 文件
    # setting.py
    
    REST_FRAMEWORK = {
        # 异常处理
        'EXCEPTION_HANDLER': 'utils.exceptions.exception_handler',
    }
    

    6. 继承 修改 DRF系统 user 模型类( 比如添加 mobile字段 )

    1. 创建、修改models.py, 使继承 user的AbstractUser类
    # apps/users/models.py
    from django.db import models
    from django.contrib.auth.models import AbstractUser
    # Create your models here.
    class User(AbstractUser):
        """用户模型类"""
        mobile = models.CharField(max_length=11, unique=True, verbose_name='手机号')
    
        class Meta:
            db_table = 'tb_users'
            verbose_name = '用户'
            verbose_name_plural = verbose_name
    
    1. 自定义的用户模型类还不能直接被Django的认证系统所识别,需要在配置文件中告知Django认证系统使用我们自定义的模型类。
    # setting.py
    
    # AUTH_USER_MODEL参数的设置以点.来分隔,表示应用名.模型类名。
    AUTH_USER_MODEL = 'users.User'
    
    

    注意:Django建议我们对于AUTH_USER_MODEL参数的设置一定要在第一次数据库迁移之前就设置好,否则后续使用可能出现未知错误。

    1. 迁移
    python manage.py makemigrations
    python manage.py migrate
    

    7. 实现 发送短信验证码接口 的一些 小技巧

    • 检查是否在60s内有发送记录
    # apps/verifications/views.py
    
    from rest_framework.generics import GenericAPIView
    from .serializers import RegisterSMSCodeSerializer
    from django_redis import get_redis_connection
    from rest_framework.response import Response
    from rest_framework import status
    from random import randint
    from libs.yuntongxun.sms import CCP
    
    
    class RegisterSMSCodeView(GenericAPIView):
        """
        获取短信验证码
        GET /verifications/smscodes/(?P<mobile>1[345789]\d{9})/?text=xxxx&image_code_id=xxxx
        获取短信验证码,首先需要校验 验证码
    
        思路:
        创建序列化器,定义text 和 image_code_id
        redis 判断该用户是否频繁获取
        生成短信验证码
        redis增加记录
        发送短信
        返回响应
        """
    
        serializer_class = RegisterSMSCodeSerializer
    
        def get(self,request,mobile):
    
            # 创建序列化器, 定义text和image_code_id
            serializer = self.get_serializer(data=request.query_params)
            serializer.is_valid(raise_exception=True)
            # redis
            redis_conn = get_redis_connection('code')
            """*****************判断该用户是否频繁获取******************"""
            if redis_conn.get('sms_flag_%s'%mobile):
                return Response(status=status.HTTP_429_TOO_MANY_REQUESTS)
            """*******************************************************"""
            # 生成短信验证码
            sms_code = '%06d'%randint(0,999999)
            # redis增加记录
            redis_conn.setex('sms_%s'%mobile,5*60,sms_code)
            """***************** 设置 标记 Flag******************"""
            redis_conn.setex('sms_flag_%s'%mobile,60,1)
            """*************************************************"""
            # 发送短信
            ccp = CCP()
            ccp.send_template_sms(mobile,[sms_code,5],1)
            # 返回响应
            return Response({'message':'ok'})
    

    8. 解决同源策略 -> 跨域CORS

    相关文章

      网友评论

          本文标题:DRF项目逻辑收录(一)

          本文链接:https://www.haomeiwen.com/subject/yckfbqtx.html