小汽车练习

drf 管理员,用户, 车,车厂,经销商 接口实现

1 有车型(CarModel),车厂(CarFactory),经销商(Distributor)三个表,一个车厂可以生产多种车型,一个经销商可以出售多种车型,一个车型可以有多个经销商出售
车型:车型名,车型出厂价,车厂id
车厂:车厂名,车厂地址,联系电话
经销商:经销商名,地址,联系电话

2 有用户表,基于django内置user表,扩展mobile字段

3 编写登陆接口,jwt方式返回token,(使用了auth的表,快速签发)
格式为{status:100,msg:登陆成功,token:safasdfa}

4 有管理员登陆后可以新增,删除车型,车厂,经销商

5 普通用户登陆可以查看车型(群查分页,单查)
查车型:返回车型信息,车厂名字,经销商名字和电话
2. 创建四表

from django.db import models

# Create your models here.

from django.contrib.auth.models import AbstractUser


class User(AbstractUser):
    mobile = models.CharField(max_length=32)
    # 可以不写,用is_superuser
    user_type = models.IntegerField(default=1, choices=((1, '管理员'), (2, '普通用户')))


class CarModel(models.Model):
    carmodel_name = models.CharField(max_length=32)
    carmodel_price = models.CharField(max_length=32)
    carfactory = models.ForeignKey(to='CarFactory', on_delete=models.CASCADE)
    distributor = models.ManyToManyField(to='Distributor')

class CarFactory(models.Model):
    carfactory_name = models.CharField(max_length=32)
    carfactory_address = models.CharField(max_length=32)
    carfactory_phone = models.CharField(max_length=32)


class Distributor(models.Model):
    distributor_name = models.CharField(max_length=32)
    distributor_address = models.CharField(max_length=32)
    distributor_phone = models.CharField(max_length=32)

有用户表,基于django内置user表,扩展mobile字段

  from django.contrib.auth.models import AbstractUser
  class User(AbstractUser):
    mobile = models.CharField(max_length=32)

在配置文件中配置

  AUTH_USER_MODEL = 'app01.user'
3 编写登陆接口
编写登陆接口,jwt方式返回token,(使用了auth的表,快速签发)
格式为{status:100,msg:登陆成功,token:safasdfa}
#配置路由
from rest_framework_jwt.views import obtain_jwt_token
  urlpatterns = [
      path('login/', obtain_jwt_token)
  ]

写一个函数,返回格式

创建utils.py文件

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

配置文件(settings)配置

import datetime

JWT_AUTH = {
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
    'JWT_RESPONSE_PAYLOAD_HANDLER': 'app01.utils.jwt_response_payload_handler'
}
# 手写认证,上边方法更简单
from rest_framework.viewsets import ViewSet
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework_jwt.settings import api_settings
from django.contrib.auth import authenticate

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, 'mag': '登录成功', 'token': token})
        else:
            return Response({'code': 101, 'mag': '用户名密码错误'})

路由

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请求
urlpatterns += router.urls

管理员登录实现操作

from rest_framework.viewsets import ModelViewSet
from .models import CarModel, CarFactory, Distributor
from .serializer import CarModelSerializer, CarFactorySerializer, DistributorSerializer
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework.permissions import IsAuthenticated
from .permission import AdminPermission
from .pagination import MyPageNumberPagination


class CarModelView(ModelViewSet):
    authentication_classes = [JSONWebTokenAuthentication, ]
    permission_classes = [IsAuthenticated, AdminPermission]
    queryset = CarModel.objects.all()
    serializer_class = CarModelSerializer
    pagination_class = MyPageNumberPagination


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

创建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

创建serializer.py文件,序列化

from .models import CarModel, CarFactory, Distributor
from rest_framework import serializers


class CarModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = CarModel
        fields = '__all__'


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


class DistributorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Distributor
        fields = '__all__'
  1. 普通用户操作

创建pagination.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

在models.py中 CarModel中修改,

class CarModel(models.Model):
    carmodel_name = models.CharField(max_length=32)
    carmodel_price = models.CharField(max_length=32)
    carfactory = models.ForeignKey(to='CarFactory', on_delete=models.CASCADE)
    distributor = models.ManyToManyField(to='Distributor')

    def car_factory_detail(self):
        return {'name': self.carfactory.carfactory_name, 'addr': self.carfactory.carfactory_phone}

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

在serializer.py修改,实现序列化

from .models import CarModel, CarFactory, Distributor
from rest_framework import serializers


class CarModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = CarModel
        fields = ['id', 'carmodel_name', 'carmodel_price', 'carfactory', 'distributor', 'car_factory_detail',
                  'distributor_detail']
        extra_kwargs = {
            'carfactory': {'write_only': True},
            'distributor': {'write_only': True},
        }
        car_factory_detail = serializers.DictField(read_only=True)
        distributor_detail = serializers.ListField(read_only=True)

路由总配置

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),  # 快速签发
]
urlpatterns += router.urls
posted @ 2023-06-04 14:48  无敌大帅逼  阅读(15)  评论(0)    收藏  举报