【 一 】搭建纯净模式
核心就是 在安装完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
【 二 】封装全局异常
-
isinstance
跟type
的区别 -
isinstance()
-
isinstance()
是一个内建函数,用于判断一个对象是否是一个已知的类型(可以是直接或间接的)。 -
它会检查对象的类型是否等于指定的类型,或者是否是从指定的类型继承而来的。
-
使用
isinstance()
是推荐的做法,因为它考虑了类的继承关系。
type()
-
type()
也是一个内建函数,它返回对象的类型。 -
对于大多数内置类型,
type()
返回的是对应的类型对象(如int
、str
、list
等)。 -
当涉及到类的继承时,
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')
-
以后视图类的方法可以写成
# 后期视图的方法,可以写成这种模板 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}
# 写一个响应类,实现 ''' -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:
: 这检查是否有传入任何额外的关键字参数(即除了code
、msg
、status
、template_name
和headers
之外的参数)。 -
data.update(kwargs)
: 如果存在额外的关键字参数,它们将被添加到data
字典中。这样,你可以通过传递额外的关键字参数来向响应中添加任意数量的字段。 -
super().__init__(data=data, status=status, headers=headers)
: 这调用父类(即原始的Response
类)的__init__
方法,并传入你已经准备好的data
、status
和headers
参数。这样,你就可以确保父类的所有功能仍然可用,并且你的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']})