【django drf】 阶段练习

需求

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

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

settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'rest_framework_jwt',
    'app01',

]
AUTH_USER_MODEL = 'app01.UserInfo'

import datetime

JWT_AUTH = {
    # 'JWT_RESPONSE_PAYLOAD_HANDLER': 'app01.utils.jwt_response_payload_handler',
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7),
}

views.py

from django.contrib import auth
from rest_framework.generics import ListAPIView, RetrieveAPIView, CreateAPIView, UpdateAPIView, \
    DestroyAPIView
from rest_framework.viewsets import ViewSet, ViewSetMixin, GenericViewSet
from .permissions import AdminPermission
from .serializers import CarModelSerializer, CarFactorySerializer, DistributorSerializer
from .models import CarModel, CarFactory, Distributor, UserInfo
from rest_framework.decorators import action
from rest_framework_jwt.settings import api_settings
from rest_framework.response import Response
from .authenticate import JsonWebTokenAuthentication
from .page import CommonCursorPagination

jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER


# 车型
class CarModelView(ViewSetMixin, ListAPIView, RetrieveAPIView):
    serializer_class = CarModelSerializer
    queryset = CarModel.objects.all()
    authentication_classes = [JsonWebTokenAuthentication, ]
    pagination_class = CommonCursorPagination


class CarModelDetailView(ViewSetMixin, CreateAPIView, UpdateAPIView, DestroyAPIView):
    serializer_class = CarModelSerializer
    queryset = CarModel.objects.all()
    authentication_classes = [JsonWebTokenAuthentication, ]
    permission_classes = [AdminPermission, ]
    pagination_class = CommonCursorPagination


# 车厂
class CarFactoryView(ViewSetMixin, ListAPIView, RetrieveAPIView):
    serializer_class = CarFactorySerializer
    queryset = CarFactory.objects.all()
    authentication_classes = [JsonWebTokenAuthentication, ]
    pagination_class = CommonCursorPagination


class CarFactoryDetailView(ViewSetMixin, CreateAPIView, UpdateAPIView, DestroyAPIView):
    serializer_class = CarFactorySerializer
    queryset = CarFactory.objects.all()
    authentication_classes = [JsonWebTokenAuthentication, ]
    permission_classes = [AdminPermission, ]
    pagination_class = CommonCursorPagination


# 经销商
class DistributorView(ViewSetMixin, ListAPIView, RetrieveAPIView):
    serializer_class = DistributorSerializer
    queryset = Distributor.objects.all()
    authentication_classes = [JsonWebTokenAuthentication, ]
    pagination_class = CommonCursorPagination


class DistributorDetailView(ViewSetMixin, CreateAPIView, UpdateAPIView, DestroyAPIView):
    serializer_class = DistributorSerializer
    queryset = Distributor.objects.all()
    authentication_classes = [JsonWebTokenAuthentication, ]
    permission_classes = [AdminPermission, ]
    pagination_class = CommonCursorPagination


class LoginView(ViewSet):
    @action(methods=['POST'], detail=False)
    def login(self, request, *args, **kwargs):
        username = request.data.get('username')
        password = request.data.get('password')
        user = auth.authenticate(request, username=username, password=password)
        if user:
            # 登录成功,签发token
            # 通过user得到payload
            payload = jwt_payload_handler(user)
            # 通过payload得到token
            token = jwt_encode_handler(payload)
            return Response({'code': 1000, 'msg': '登录成功', 'token': token})
        else:
            return Response({'code': 1001, 'msg': '用户名或密码错误'})


# 注册接口
class RegisterView(ViewSet, CreateAPIView):
    @action(methods=['POST'], detail=False)
    def register(self, request, *args, **kwargs):
        username = request.data.get('username')
        password = request.data.get('password')
        user = UserInfo.objects.filter(username=username).first()
        if user:
            return Response({'code': 1000, 'msg': '用户名已存在'})
        else:
            UserInfo.objects.create_user(username=username, password=password)
            return Response({'code': 1001, 'msg': '注册成功'})

urls.py


from django.contrib import admin
from django.urls import path
from rest_framework.routers import SimpleRouter
from app01 import views

router = SimpleRouter()
# 车型
router.register('api/v1/car_model', views.CarModelView, 'car_model')
router.register('api/v1/car_model_admin', views.CarModelDetailView, 'car_model_admin')
# 车厂
router.register('api/v1/car_factory', views.CarFactoryView, 'car_factory')
router.register('api/v1/car_factory_admin', views.CarFactoryDetailView, 'car_factory_admin')
# 经销商
router.register('api/v1/distributor', views.DistributorView, 'distributor')
router.register('api/v1/distributor_admin', views.DistributorDetailView, 'distributor_admin')
# 登录
router.register('api/v1', views.LoginView, '')
# 注册
router.register('api/v1/user', views.RegisterView, 'user')
urlpatterns = [
    path('admin/', admin.site.urls),
]

urlpatterns += router.urls

serializers.py

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


class CarModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = CarModel
        fields = ['name', 'price', 'factory_detail', 'distributor_list', 'factory', 'distributors']
        extra_kwargs = {
            'factory_detail': {'read_only': True},
            'distributor_list': {'read_only': True},
            'factory': {'write_only': True},
            'distributors': {'write_only': True},
        }


class CarFactorySerializer(serializers.ModelSerializer):
    class Meta:
        model = CarFactory
        fields = ['name', 'address', 'phone']


class DistributorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Distributor
        fields = ['name', 'address', 'phone']

permissions.py

from rest_framework.permissions import BasePermission


class AdminPermission(BasePermission):
    def has_permission(self, request, view):
        if request.user.is_superuser == 1:
            return True
        else:
            self.message = '您没有权限'
            return False

page.py

from rest_framework.pagination import CursorPagination


class CommonCursorPagination(CursorPagination):
    cursor_query_param = 'cursor'  # 查询参数
    page_size = 5  # 每页多少条
    ordering = 'id'  # 排序字段

authenticate.py

from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
import jwt
from .models import UserInfo
from rest_framework_jwt.settings import api_settings

jwt_decode_handler = api_settings.JWT_DECODE_HANDLER


class JsonWebTokenAuthentication(BaseAuthentication):
    def authenticate(self, request):
        token = request.META.get('HTTP_TOKEN')
        if token:
            try:
                payload = jwt_decode_handler(token)
                user = UserInfo.objects.get(pk=payload.get('user_id'))
                return user, token
            except jwt.ExpiredSignature:
                raise AuthenticationFailed('token过期')
            except jwt.DecodeError:
                raise AuthenticationFailed('token认证失败')

            except jwt.InvalidTokenError:
                raise AuthenticationFailed('token无效')
            except Exception as e:
                raise AuthenticationFailed('未知异常')

        raise AuthenticationFailed('token没有传,认证失败')

model.py

from django.db import models


from django.db import models

from django.contrib.auth.models import AbstractUser


class UserInfo(AbstractUser):
    # 填写AbstractUser表中没有的字段
    phone = models.BigIntegerField(null=True)


class CarModel(models.Model):
    name = models.CharField(max_length=32)
    price = models.CharField(max_length=32)
    factory = models.ForeignKey(to='CarFactory', on_delete=models.CASCADE)
    distributors = models.ManyToManyField(to='Distributor')

    def factory_detail(self):
        return {'name': self.factory.name, 'address': self.factory.address, 'phone': self.factory.phone}

    def distributor_list(self):
        return [{'name': distr.name, 'address': distr.address, 'phone': distr.phone}
                for distr in self.distributors.all()]


class CarFactory(models.Model):
    name = models.CharField(max_length=32)
    address = models.TextField(max_length=32)
    phone = models.CharField(max_length=32)


class Distributor(models.Model):
    name = models.CharField(max_length=32)
    address = models.TextField(max_length=32)
    phone = models.CharField(max_length=32)

权限类判断请求方式

image
注意:
image

posted @ 2023-02-13 19:59  passion2021  阅读(65)  评论(0编辑  收藏  举报