drf 测试(车型、车场、经销商)

一、实现要求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
1 有车型(CarModel),车厂(CarFactory),经销商(Distributor)三个表,一个车厂可以生产多种车型,一个经销商可以出售多种车型,一个车型可以有多个经销商出售
 
车型:车型名,车型出厂价,车厂id
 
车厂:车厂名,车厂地址,联系电话
 
经销商:经销商名,地址,联系电话
 
2 有用户表,基于django内置user表,扩展mobile字段
 
3 编写登陆接口,jwt方式返回token,
格式为{status:100,msg:登陆成功,token:safasdfa}
 
4 所有接口(除登录外),必须登录后才能访问
 
5 管理员登陆后可以增,删,单查,群查,改 车型,车厂,经销商(具备所有接口权限)
 
6 普通用户登陆可以查看车型,车厂,经销商单条,所有(只有查看权限)
 
7 所有查询所有接口带分页功能
 
8 查询所有车型接口,可以按车型名字精准过滤
 
加分项:
用户注册接口
管理员有用户锁定,删除用户功能 

注:

根据信息提取出表关系:车型和车场:一对多,车型和经销商:多对多

Models:

views视图类导入模块汇总

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from rest_framework.response import Response
from rest_framework_jwt.settings import api_settings
from django.contrib.auth import authenticate
from rest_framework.viewsets import ViewSet, ModelViewSet
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import CreateModelMixin, DestroyModelMixin
from .models import CarModel, CarFactory, Distributor
from .serializer import CarModelSerializer, CarFactorySerializer, DistributorSerializer, UserSerializer
from .page import CommonPageNumberPagination
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from .permissions import UserPermission
from .models import User
from rest_framework.views import APIView
from rest_framework.decorators import action
 
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

二、注册登录接口

1、登录

使用authenticate 方法去比对验证加密后的密码

1
2
3
4
5
6
7
8
9
10
11
class LoginView(APIView):
    def post(self, request):
        username = request.data.get('username')
        password = str(request.data.get('password'))
        user_obj = authenticate(request, username=username, password=password)
        if user_obj:
            payload = jwt_payload_handler(user_obj)
            token = jwt_encode_handler(payload)
            return Response({'status': 100, 'msg': '登录成功', 'token': token, 'username': user_obj.username})
        else:
            return Response({'status': 101, 'msg': '用户名或密码错误'})

2、注册

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class UserView(ViewSet, GenericAPIView, CreateModelMixin):  # ViewSet =ViewSetMixin + APIView
    queryset = User.objects.all()
    serializer_class = UserSerializer
 
    def create(self, request, *args, **kwargs):
        ser = self.get_serializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': '注册成功!', 'result': ser.data})
        return Response({'status': 101, 'msg': '注册失败!', 'erros': ser.errors})
 
 
######
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['username', 'password', 'mobile']
        extra_kwargs = {
            'password': {'write_only': True}
        }
 
    def create(self, validated_data):
        user = User.objects.create_user(**validated_data)
        return user

三、权限管理、分页、JWT、过滤

1、views

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 车型
class CarModelView(ModelViewSet):
    queryset = CarModel.objects.all()
    serializer_class = CarModelSerializer
    pagination_class = CommonPageNumberPagination  # 分页
    authentication_classes = [JSONWebTokenAuthentication]   # 签发token
    permission_classes = [IsAuthenticated, UserPermission]  # IsAuthenticated 只有token认证通过的可以访问视图。  UserPermission验证用户的权限
    filter_backends = [DjangoFilterBackend]  # 过滤
    filterset_fields = ['carmodel_name', 'carfact_price']
 
 
# 车厂
class CarFactoryView(ModelViewSet):
    queryset = CarFactory.objects.all()
    serializer_class = CarFactorySerializer
    pagination_class = CommonPageNumberPagination  # 分页
    # authentication_classes = [JSONWebTokenAuthentication]
    # permission_classes = [IsAuthenticated, UserPermission]
    filter_backends = [DjangoFilterBackend]  # 过滤
    filterset_fields = ['carfact_name', 'carfact_phone']
 
 
# 经销商
class DistributorView(ModelViewSet):
    queryset = Distributor.objects.all()
    serializer_class = DistributorSerializer
    pagination_class = CommonPageNumberPagination  # 分页
    authentication_classes = [JSONWebTokenAuthentication, ]
    permission_classes = [IsAuthenticated, UserPermission]
    filter_backends = [DjangoFilterBackend]  # 过滤
    filterset_fields = ['dist_name', 'dist_phone']

2、分页类

1
2
3
4
5
6
7
8
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination
 
class CommonPageNumberPagination(PageNumberPagination):
    # 重写几个类属性
    page_size = 3  # 每页显示多少条
    page_query_param = 'page'  # 指定第几页的key值 http://127.0.0.1:8000/books/?page=3
    page_size_query_param = 'size'  # 可以指定每页显示多少条 size=300000
    max_page_size = 5

3、自定义的认证类

判断用户的角色和请求方法,普通用户只能有查看单条和查看所有的权限

1
2
3
4
5
6
7
8
from rest_framework.permissions import BasePermission
from rest_framework.exceptions import AuthenticationFailed
 
class UserPermission(BasePermission):
    def has_permission(self, request, view):
        if not request.user.is_superuser and request.method != 'GET':   # 如果是普通用户,只能查看所有或者单条,没修改、更新、创建权限
            raise AuthenticationFailed('You must be a superuser')
        return True

四、管理员有用户锁定,删除用户功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#  管理员有用户锁定,删除用户功能
class AdminView(ViewSet, GenericAPIView, DestroyModelMixin):
    queryset = User.objects.all()
    authentication_classes = [JSONWebTokenAuthentication]
    permission_classes = [IsAuthenticated, IsAdminUser]  # IsAdminUser普通用户不能使用这个接口
 
    @action(methods=['DELETE'], detail=True)
    # 重写于DestroyModelMixin的delete方法
    def delete_user(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)
 
    @action(methods=['GET'], detail=True)
    def lock(self, request, *args, **kwargs):
        user = self.get_object()
        if user is None:
            return Response({'status': 101, 'msg': '用户不存在!'})
        if user.is_active:
            user.is_active = False
            user.save()
            return Response({'status': 100, 'msg': '用户锁定成功!'})
        else# is_active为0的情况
            return Response({'status': 102, 'msg': '用户已经锁定,请勿重复操作!'})
 
    @action(methods=['GET'], detail=True)
    def unlock(self, request, *args, **kwargs):
        user = self.get_object()
        if user is None:
            return Response({'status': 101, 'msg': '用户不存在!'})
        if user.is_active is False:
            user.is_active = True
            user.save()
            return Response({'status': 100, 'msg': '用户解锁成功!'})
        else:
            return Response({'status': 102, 'msg': '用户没有锁定,请勿重复操作!'})

五、序列化类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
from rest_framework import serializers
from .models import CarModel, CarFactory, Distributor
from .models import User
 
 
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['username', 'password', 'mobile']
        extra_kwargs = {
            'password': {'write_only': True}
        }
 
    def create(self, validated_data):
        user = User.objects.create_user(**validated_data)
        return user
 
 
class CarModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = CarModel
        fields = '__all__'
 
        extra_kwargs = {
            'carmodel_name': {'max_length': 8, 'min_length': 3},
            'distributor': {'write_only': True},
            'carfact': {'write_only': True}
        }
 
    carfact_detail = serializers.SerializerMethodField()
 
    def get_carfact_detail(self, obj):
        return {'name': obj.carfact.carfact_name, 'addr': obj.carfact.carfact_addr}
 
    distributor_detail = serializers.SerializerMethodField()
 
    def get_distributor_detail(self, obj):
        l = []
        for i in obj.distributor.all():
            l.append({'name': i.dist_name, 'addr': i.dist_addr, 'phone': i.dist_phone})
            return l
 
 
class CarFactorySerializer(serializers.ModelSerializer):
    class Meta:
        model = CarFactory
        fields = '__all__'
 
 
class DistributorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Distributor
        fields = '__all__'

六、路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from django.urls import path, include
from rest_framework.routers import SimpleRouter
from app01.views import CarModelView, CarFactoryView, DistributorView, UserView, AdminView,LoginView
 
route = SimpleRouter()
route.register('user', UserView, 'user')
route.register('admin', AdminView, 'admin')
route.register('carmodel', CarModelView, 'carmodel')
route.register('carfact', CarFactoryView, 'carfact')
route.register('dict', DistributorView, 'dict')
 
urlpatterns = [
    path('login/', LoginView.as_view()),
    path('', include(route.urls))
 ]

  

 

posted @   凡人半睁眼  阅读(75)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探
历史上的今天:
2019-09-26 用linux主机做网关搞源地址转换(snat)

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示