drf-车辆管理系统作业

考试要求:
1 有车型(CarModel),车厂(CarFactory),经销商(Distributor)三个表,一个车厂可以生产多种车型,一个经销商可以出售多种车型,一个车型可以有多个经销商出售
  车型:车型名,车型出厂价,车厂id
  车厂:车厂名,车厂地址,联系电话
  经销商:经销商名,地址,联系电话
2 有用户表,基于django内置user表,扩展mobile字段
3 编写登陆接口,jwt方式返回token,
	格式为{status:100,msg:登陆成功,token:safasdfa}
3 有管理员登陆后可以新增,删除车型,车厂,经销商
2 普通用户登陆可以查看车型(群查分页,单查)
	查车型:返回车型信息,车厂名字,经销商名字和电话

加分项:
用户注册接口
管理员有用户锁定,删除功能

models.py:
from django.db import models

# Create your models here.
from django.contrib.auth.models import AbstractUser


#python 中定义变量,文件,都用 下划线
# 除了类名以外,不要用驼峰,大小写
# 全大写表示常量

class User(AbstractUser): # 配置文件中配置
    mobile = models.CharField(max_length=32)


class CarModel(models.Model):
    # 车型名,车型出厂价,车厂id
    name = models.CharField(max_length=32)
    price = models.CharField(max_length=32)

    car_factory = models.ForeignKey(to='CarFactory',on_delete=models.CASCADE)

    distributor = models.ManyToManyField(to='Distributor')

    def car_factory_detail(self):
        return {'name': self.car_factory.name, 'addr': self.car_factory.address}

    def distributor_detail(self):
        l = []
        for item in self.distributor.all():
            l.append({'name': item.name, 'addr': item.address, 'mobile': item.mobile})
        return l


class CarFactory(models.Model):
    # 车厂名,车厂地址,联系电话
    name = models.CharField(max_length=32)
    address = models.CharField(max_length=32)
    mobile = models.CharField(max_length=32)


class Distributor(models.Model):
    # 经销商名,地址,联系电话
    name = models.CharField(max_length=32)
    address = models.CharField(max_length=32)
    mobile = models.CharField(max_length=32)

views.py:
from rest_framework.viewsets import ModelViewSet
from .models import *
from .serializer import *
from .page import MyPageNumberPagination
from rest_framework.permissions import IsAuthenticated
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from .permission import AdminPermission
from rest_framework.views import APIView
from rest_framework.viewsets import ViewSet
from rest_framework.decorators import action
from django.contrib.auth import authenticate
from rest_framework_jwt.settings import api_settings
from rest_framework.response import Response

jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER


class UserView(ViewSet):
    @action(methods=['POST'], detail=False)
    def login(self, request):
        username = request.data.get('username')
        password = request.data.get('password')
        user = authenticate(username=username, password=password)
        if user:
            # 通过user拿到payload
            payload = jwt_payload_handler(user)
            # 通过payload拿到token
            token = jwt_encode_handler(payload)
            return Response({'code': 100, 'msg': '登录成功', 'token': token})
        else:
            return Response({'code': 101, 'msg': '用户名或密码错误'})


class CarModelView(ModelViewSet):
    authentication_classes = [JSONWebTokenAuthentication]
    permission_classes = [IsAuthenticated, AdminPermission]
    queryset = CarModel.objects.all()
    serializer_class = CarModelSerializer
    pagination_class = MyPageNumberPagination
"""
authentication_classes = [JSONWebTokenAuthentication]:校验token有没有传,如果传错则无法校验,不传则会正常通过拿到数据。
permission_classes = [IsAuthenticated]:校验是否登陆,配合这个方法必须要上传token(拿到token说明已经登陆)
"""

class CarFactoryView(ModelViewSet):
    authentication_classes = [JSONWebTokenAuthentication]
    permission_classes = [IsAuthenticated, AdminPermission]
    queryset = CarFactory.objects.all()
    serializer_class = CarFactorySerializer


class DistributorView(ModelViewSet):
    authentication_classes = [JSONWebTokenAuthentication]
    permission_classes = [IsAuthenticated, AdminPermission]
    queryset = Distributor.objects.all()
    serializer_class = DistributorSerializer
"""
用postman向后端传数据时,不能带任何形式的注释。如果将json格式字符串复制到https://www.json.cn/ 中json格式数据不能显示,那么也无法像后端发送。
"""

permission.py:
from rest_framework.permissions import BasePermission


class AdminPermission(BasePermission):
    def has_permission(self, request, view):
        if request.user.is_superuser:
            return True
        else:
            # 不是超级用户,只能访问get
            if request.method == 'GET':
                return True
            else:
                return False
				
urls.py:
from django.contrib import admin
from django.urls import path
from app01 import views
from rest_framework_jwt.views import obtain_jwt_token
from rest_framework.routers import SimpleRouter

router = SimpleRouter()
router.register('user', views.UserView, 'user')  # /user/login--->post请求

router.register('car_model', views.CarModelView, 'car_model')
router.register('car_factory', views.CarFactoryView, 'car_factory')
router.register('distributor', views.DistributorView, 'distributor')
urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/', obtain_jwt_token),  # 快速签发
    # path('user/', views.UserView.as_view()), # /user/login--->post请求
]

urlpatterns += router.urls

utils.py:

def jwt_response_payload_handler(token, user=None, request=None):
    return {
        'status': 100,
        'msg': '登录成功',
        'username':user.username,
        'token': token,

    }
	
serializer.py:
from .models import *
from rest_framework import serializers


class CarModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = CarModel
        fields = ['id', 'name', 'price', 'car_factory', 'distributor', 'car_factory_detail', 'distributor_detail']  # CarModel中有两个只读字段所以要全写出来
        extra_kwargs = {
            'car_factory': {'write_only': True},
            'distributor': {'write_only': True},
        }

    car_factory_detail = serializers.DictField(read_only=True)
    distributor_detail = serializers.ListField(read_only=True)


class CarFactorySerializer(serializers.ModelSerializer):
    class Meta:
        model = CarFactory
        fields = '__all__'


class DistributorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Distributor
        fields = '__all__'
		
page.py:
from rest_framework.pagination import PageNumberPagination


class MyPageNumberPagination(PageNumberPagination):
    page_size = 2
    page_query_param = 'page'
    page_size_query_param = 'size'
    max_page_size = 5

posted @ 2023-02-13 22:34  ERROR404Notfound  阅读(11)  评论(0)    收藏  举报
Title