Djngo项目创建的准备工作【5】

【 一 】搭建纯净模式

核心就是 在安装完drf之后记得在app里面注册'rest_framework',

# django 默认很多app--》很多表
    auth 6个表
    session 表
    content-type表
# django很多中间件
​
# 以后我们的项目,可能不用这些东西---》由于带了内置app,这些表就会创建
​
# 后期如果项目的用户表,不用auth的user表,做成纯净环境
    -1 删除所有app
    -2 删除所有中间件
    -3 安装drf
    -4 配置:
        REST_FRAMEWORK = {
            "UNAUTHENTICATED_USER": None,
        }

  • 步骤 1: 创建新的Django项目和应用

首先,你需要使用Django的命令行工具来创建一个新的项目和应用。

# 创建一个新的Django项目  
django-admin startproject myproject  
  
# 进入项目目录  
cd myproject  
  
# 创建一个新的应用(比如 user_app)  
python manage.py startapp user_app
  • 步骤 2: 修改项目的settings.py

myproject/settings.py文件中,确保你的INSTALLED_APPS包含了你的新应用user_app。同时,将MIDDLEWARE列表设置为空(请注意,这在实际项目中是不推荐的):

# myproject/settings.py  
  
INSTALLED_APPS = [  
    # ...  
    'user_app',  
    # ...  
]  
  
MIDDLEWARE = []  # 注意:这在实际项目中是不推荐的
  • 步骤 3: 在user_app中创建views.py

user_app/views.py文件中,你可以编写一个简单的视图来渲染一个模板。首先,确保从django.shortcuts中导入了render函数。

# user_app/views.py  
  
from django.shortcuts import render  
  
def home(request):  
    # 这里可以添加一些逻辑来处理请求,但在这个例子中我们直接渲染模板  
    return render(request, 'home.html')
  • 步骤 4: 创建urls.py和home.html

user_app目录下,创建一个urls.py文件来定义你的URL模式。然后,在项目的urls.py中包含这个应用的URL配置。

# myproject/urls.py  
from django.contrib import admin  
from django.urls import include, path  
  
urlpatterns = [  
    path('admin/', admin.site.urls),  
    path('', include('user_app.urls')),  # 引入user_app的URL配置  
]  
  
# user_app/urls.py  
from django.urls import path  
from . import views  
  
urlpatterns = [  
    path('', views.home, name='home'),  
]

接着,在user_app/templates/user_app/目录下创建home.html模板文件(确保你的Django项目配置中的TEMPLATES'DIRS'设置包含了该模板目录的路径)。

<!-- user_app/templates/user_app/home.html -->  
<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <title>Home Page</title>  
</head>  
<body>  
    <h1>Welcome to the Home Page!</h1>  
</body>  
</html>
  • 步骤 5: 运行开发服务器

最后,你可以运行Django的开发服务器来查看你的应用是否按预期工作。

# 在myproject目录下运行  
python manage.py runserver

【 二 】封装全局异常

  • isinstancetype的区别

  • isinstance()

    • isinstance() 是一个内建函数,用于判断一个对象是否是一个已知的类型(可以是直接或间接的)。

    • 它会检查对象的类型是否等于指定的类型,或者是否是从指定的类型继承而来的。

    • 使用 isinstance() 是推荐的做法,因为它考虑了类的继承关系。

    type()

    • type() 也是一个内建函数,它返回对象的类型。

    • 对于大多数内置类型,type() 返回的是对应的类型对象(如 intstrlist 等)。

    • 当涉及到类的继承时,type() 只返回对象的直接类型,而不会考虑它的超类。

    • 使用 type() 来比较类型时,它只会检查对象的直接类型,而不考虑继承。

  • 自定义的异常捕获在公共utils创建exception.py文件

​
from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework.views import Response
from rest_framework import status
# 导入自定义日志
from .logg import logger
import logging
​
​
logging.getLogger('django')
# 以后可能会自定义自定义异常类
class NoPermissionException(Exception):
    pass # # 不需要额外的__init__方法,除非你需要额外的功能
​
​
​
def exception_handler(exc, context):
    # 记录日志
    # 只要执行到这,一定以为着程序出现了异常,记录日志
    resquest = context.get('request')
    user = resquest.user.id or '【 匿名用户 】'
    path = resquest.get_full_path()
    view = str(context.get('view'))
    ip = resquest.META.get("REMOTE_ADDR")
    error = str(exc)
    logger.error('用书:[%s],访问路径:[%s],视图类是:[%s],客户端地址:[%s],出差了,错误信息是:[%s]'
                 % (user, path, view, ip, error))  # 这就是基本规划
​
    res = drf_exception_handler(exc, context)
    # 我们将这些进行细分的区分异常 804 888 806 分别代表什么
​
    if res:
        # drf的异常 data=['错误1',错误2]    data={detail:'sss'}
        if isinstance(res.data, dict):
            err = res.data.get('detail')
        elif isinstance(res.data, list):
            err = res.data[0]
        else:
            err = '服务异常,请稍后再尝试,-drf'
        response = Response({'code': 999, 'msg': err})
    else:
        # 非drf异常,更细力度的区分异常
        if isinstance(exc, ZeroDivisionError):
            err = '数据操作出错,除以0了'
            code = 909
        elif isinstance(exc, NoPermissionException):
            err = f'您没有操作权限:{str(exc)}'
            code = 906
        else:
            err = f'系统错误:{str(exc)}'
            code = 909
        response = Response({'code': code, 'msg': err})
​
    return response
  • 配置文件新的dev.py

#  封装异常处理
REST_FRAMEWORK = {
    # 文件名.函数名
    'EXCEPTION_HANDLER': 'lufy.utils.exception.exception_handler',
}

  • 子路由user/urls.py

from django.urls import path
from . import views
from .views import LoggerView, ExceptionView
​
urlpatterns = [
    path('logg/', LoggerView.as_view(), name='home'),
    path('except/', ExceptionView.as_view()),
]
​

  • 子路由user/view.py

​
from rest_framework.response import Response
from rest_framework.views import APIView
# 日志
from lufy.utils.logg import logger
# 异常的包
from rest_framework.exceptions import ValidationError,AuthenticationFailed,APIException
# 自定义异常捕获
from lufy.utils.exception import NoPermissionException
​
class LoggerView(APIView):
    def get(self,request):
        logger.info('来了,老弟')
        return Response('ok')
​
​
class ExceptionView(APIView):
    def get(self,request):
        # drf异常
        # 主动抛出异常!!!
        # x = 1/0
        # print(x)
        # raise ZeroDivisionError('失败了这么棒!!。人生当苦无妨,良人当归便好。')
        # # {
        # #     "code": 909,
        # #     "msg": "数据操作出错,除以0了"
        # # }
​
        try:
            # 这里是你可能会出现除零错误的代码
            res = 1 / 0
        except ZeroDivisionError:
            # 捕获除零错误,并抛出 NoPermissionException 异常
            raise NoPermissionException('4564') # 这个就是自定义的报错
            
            # {     
            #     "code": 906,
            #     "msg": "您没有操作权限:4564"
            # }
​
        return Response('ok')
​

image-20240510162645359

image-20240510162855878

  • 以后视图类的方法可以写成

# 后期视图的方法,可以写成这种模板
try:
    # 核心逻辑
    if 某个条件不符合:  # 或断言
        raise NoPermissionException
    except NoPermissionException as e:
        # return Response({'code':888,'msg':'错误'})
        raise NoPermissionException('没有权限')
    except AAException as e:
        raise NoPermissionException('没有权限')
        return Response('ok')

【 三 】二次封装Response模块

  • Response这个就是前端我们看到的数据

# 响应---》drf提供的Response---》前端想接收到的格式
    {code:xx,msg:xx}

image-20240510163852988

# 写一个响应类,实现
'''
    -APIResponse()--->{code:100,msg:成功}
    -APIResponse(code=101,msg='失败')--->{code:101,msg:失败}
    -APIResponse(username=lqz,token:adsfa.as.ss,icon:头像地址)--->{code:100,msg:成功,username:lqz,token:adsfa.as.ss,icon:头像地址}
    
    -APIResponse(results=[{},{}])--->{code:100,msg:成功,results=[{},{}]}
   
    -APIResponse(headers={})--->{code:100,msg:成功,results=[{},{}]}    '''
  • 开始封装

  • code=100, msg='成功响应!!!': 这是APIResponse类的默认参数,表示当没有提供其他参数时,响应将包含一个状态码100和一条消息'成功响应!!!'

  • if kwargs:: 这检查是否有传入任何额外的关键字参数(即除了codemsgstatustemplate_nameheaders之外的参数)。

  • data.update(kwargs): 如果存在额外的关键字参数,它们将被添加到data字典中。这样,你可以通过传递额外的关键字参数来向响应中添加任意数量的字段。

  • super().__init__(data=data, status=status, headers=headers): 这调用父类(即原始的Response类)的__init__方法,并传入你已经准备好的datastatusheaders参数。这样,你就可以确保父类的所有功能仍然可用,并且你的APIResponse类将作为一个完整的、可工作的响应对象。

  • 在lufy/utils/utils_Response.py

from rest_framework.response import Response
​
​
class APIResponse(Response):
    '''
    源码里面的数据
        def __init__(self, data=None, status=None,
                 template_name=None, headers=None,
                 exception=False, content_type=None):
​
    我们就是要先重写Response里面的__init__
    '''
​
    def __init__(self, code=100, msg='成功响应!!!', status=None, template_name=None, headers=None, **kwargs):
        data = {'code': code, 'msg': msg}
        if kwargs:
            data.update(kwargs)
        super().__init__(data=data, status=status, headers=headers)
  • 子路由user/urls.py

from django.urls import path
from . import views
from .views import LoggerView, ExceptionView,ResponseView
​
urlpatterns = [
    # 日志
    path('logg/', LoggerView.as_view(), name='home'),
    # 异常
    path('excet/', ExceptionView.as_view()),
    # 响应方法
    path('ponse/', ResponseView.as_view()),
]
  • 子路由user/view.py

from lufy.utils.utils_response import APIResponse
​
class ResponseView(APIView):
    def get(self, request, *args, **kwargs):
        # return APIResponse(name="shazi",password='123123132',token='asdas.da.dasd')
        # return APIResponse(results=[{"user":'132'},{"hobby":['music','running']}])
        return APIResponse(headers={"hobby":['music','running']})

image-20240510165941190

---------------------------------------------------------------------------------------------------------------------------------------

image-20240511164706708

  • 17
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值