django rest framework工程化

本文介绍了如何利用djangorestframework建立RESTful风格的API框架,包括项目结构设计,如apps、async_tasks、core、log、templates和utils目录的用途。重点讲述了登录基础,采用djangorestframework-simplejwt进行JWT认证,并自定义了TokenObtainPairSerializer进行登录验证。此外,文章还涵盖了DRF的基础设置,如路由、视图、序列化以及自定义分页和响应类。

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

基本框架搭建

1. 概述

django rest framework 为django衍生系列框架,用于restful风格,本次搭建旨在更好的进行代码开发,用于快速集成业务代码的书写,省略了基础的架子搭建工作

2. 模块结构

drf工程化结构如下:

| ├── project
│ ├── apps
│ ├── async_tasks
│ ├── core
│ ├── log
│ ├── templates
│ ├── utils
│ └── README.md

在这里插入图片描述

  • apps目录是django多个应用的合集,集中在一个文件夹下方便管理
  • async_tasks目录是异步任务定时任务的配置以及任务代码的集合
  • core是项目的入口配置文件集合
  • log日志文件目录
  • utils是工具集包括项目架子所需要的重写的部分以及自定义的代码集合

3. 登录基础

该项目采用djangorestframework-simplejwt

pip install djangorestframework-simplejwt

# 在setting中配置认证插件
REST_FRAMEWORK = {
  'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework_simplejwt.authentication.JWTAuthentication',
  )} 
# 注册应用
INSTALLED_APPS=['rest_framework_simplejwt',]
# 配置认证插件的参数
SIMPLE_JWT = {
  'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
  'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
  'USER_ID_FIELD': 'id',
  'ALGORITHM': 'HS256',
  'SIGNING_KEY': SECRET_KEY,
  'AUTH_HEADER_TYPES': ('Bearer',),
  'TOKEN_USER_CLASS': 'account.models.User'
}

重写TokenObtainPairSerializer用于登录认证

class LoginSerializer(TokenObtainPairSerializer):
    username = CharField(required=True)
    password = CharField(required=True)

    
    def validate(self, attrs):
        """
        验证
        """
        redis_conn = get_redis_connection('default')
        username = attrs["username"]
        # 效验是否锁定
        # if redis_conn.get(username):
        #     raise CustomException(message='账户已锁定,请等待')
        try:
            return super().validate(attrs)
        except exceptions.AuthenticationFailed:
            raise CustomException(message='密码或者用户名不正确')

4.drf基础

该项目采用标准的drf工程进行开发,路由层采用urls+routers配合使用, 视图层以ModelViewSet为主,Mixin系列为辅进行view层开发,

序列化层则采用ModelSerializer+Serializer配合。

  • drf基础搭建示例代码

    # settings.py
    INSTALLED_APPS=['rest_framework', 'django_filters',]
    
    REST_FRAMEWORK = {
        'DEFAULT_PARSER_CLASSES': (
            'rest_framework.parsers.JSONParser',
        ),
        'DEFAULT_RENDERER_CLASSES': (
            'rest_framework.renderers.JSONRenderer',
        ),
        # 身份认证
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.BasicAuthentication',
            'rest_framework.authentication.SessionAuthentication',
            'rest_framework_simplejwt.authentication.JWTAuthentication',
        ),
        # 自定义权限认证
        # 'DEFAULT_PERMISSION_CLASSES': ('utils.permissions.CustomPermission',),
        # 自定义分页
        'DEFAULT_PAGINATION_CLASS': 'utils.pagination.PageNumberPagination',
        # django过滤
        'DEFAULT_FILTER_BACKENDS': (
            'django_filters.rest_framework.DjangoFilterBackend',
        ),
        # 自定义异常
        'EXCEPTION_HANDLER': 'utils.exceptions.exc_handler'
    }
    # pagination.py
    class PageNumberPagination(pagination.PageNumberPagination):
        max_page_size = 999999999
        page_size_query_param = 'limit'
        page_query_description = '页数'
        invalid_page_message = '已经没有更多了'
    
        def get_paginated_response(self, data):
            page_size = self.get_page_size(self.request)
            return Response({
                'paging': {
                    'limit': page_size,
                    'total': min(self.page.paginator.count, self.max_page_size),
                    'page': self.page.number,
                    'total_pages': self.page.paginator.num_pages,
                },
                'results': data
            })
    # response.py
    from rest_framework.response import Response
    
    class Response(Response):
        """
        自定义response
        """
    
        def __init__(self, data=[], status=200, code=200, message='success', template_name=None,
                     headers=None, exception=False, content_type=None):
            super().__init__(data, status, template_name, headers, exception, content_type)
    
            self.data = {
                'data': data,
                'code': code,
                'message': message
            }
      
    

简单通过一个user例子完成drf框架基本的使用:

  • UserModel创建
class User(AbstractUser):
    username = models.CharField(max_length=128, verbose_name='用户名', unique=True, db_index=True)
    mobile = models.CharField(max_length=32, blank=True, null=True, help_text='手机号')

    class Meta:
        db_table = 'account_users'
        verbose_name = '用户表'
  • ​ UserSerializer创建
class UserSerializer(ModelSerializer):
    class Meta:
        model = User
        exclude = ()
        read_only_fields = ('create_at', 'modify_at')
  • UserViewSet创建
class UserViewSet(ModelViewSet):
    serializer_class = UserSerializer
    queryset = User.objects.order_by('-id')
    permission_classes = []

    def get_queryset(self):
        return self.queryset
  • UrlRouter创建
# routers.py
from rest_framework import routers
from apps.account.views import UserViewSet

router = routers.DefaultRouter()
router.trailing_slash = '/?'
router.register(r'users', UserViewSet, basename="user")

# urls.py
from django.contrib import admin
from django.urls import path, include
from core.routers import router

urlpatterns = [
    path('admin/', admin.site.urls),
    path(r'api/', include(router.urls)),
]
  • 登录在这里插入图片描述

  • users列表
    在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值