数据
from django.db import models
class User(models.Model):
username = models.CharField(max_length=64, verbose_name='用户名')
password = models.CharField(max_length=64, verbose_name='密码')
user_type = models.IntegerField(choices=((1, '菜鸟用户'), (2, '普通用户'), (3, '超级用户')), verbose_name='用户级别')
class UserToken(models.Model):
token = models.CharField(max_length=64, verbose_name='随机字符串')
user = models.OneToOneField(to=User, on_delete=models.CASCADE)
class Book(models.Model):
title = models.CharField(max_length=32, verbose_name='书名')
price = models.IntegerField(verbose_name='书价')
publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
users = models.ManyToManyField(to=User)
def publish_detail(self):
return {'name': self.publish.name, 'addr': self.publish.addr}
def user_list(self):
lst = []
for user in self.users.all():
lst.append({
'username': user.username,
'password': user.password,
'user_type': user.get_user_type_display()
})
class Publish(models.Model):
name = models.CharField(max_length=32, verbose_name='出版社名称')
addr = models.CharField(max_length=32, verbose_name='出版社地址')
路由
from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import DefaultRouter, SimpleRouter
from app01.views import BookView
router = SimpleRouter()
router.register('books', BookView, 'books')
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(router.urls))
]
序列化类
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from .models import User, UserToken, Book, Publish
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = '__all__'
class PublishSerializer(serializers.ModelSerializer):
class Meta:
model = Publish
fields = '__all__'
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ['title', 'price', 'publish', 'users', 'publish_detail', 'user_list']
extra_kwargs = {
'publish': {'write_only': True},
'users': {'write_only': True},
}
publish_detail = serializers.DictField(read_only=True)
user_list = serializers.ListField(read_only=True)
def validate_users(self, value):
if len(value) > 5:
raise ValidationError('一本图书的作者最多5个')
return value
def validate(self, attrs):
title = attrs.get('title')
publish = attrs.get('publish')
sensitive_words = ['SB', 'DJB', 'CNM']
for word in sensitive_words:
if word in title:
raise ValidationError('标题包含敏感信息')
if word in publish:
raise ValidationError('出版社名称包含敏感信息')
return attrs
分页 page.py
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination
class CommonPageNumberPagination(PageNumberPagination):
page_size = 3
page_query_param = 'page'
page_size_query_param = 'size'
max_page_size = 5
class CommonLimitOffsetPagination(LimitOffsetPagination):
default_limit = 2
limit_query_param = 'limit'
offset_query_param = 'offset'
max_limit = 5
class CommonCursorPagination(CursorPagination):
cursor_query_param = 'cursor'
page_size = 2
ordering = 'id'
视图函数
PageNumberPagination
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from .models import Book
from .serializer import BookSerializer
from rest_framework.viewsets import ViewSetMixin
from .page import CommonPageNumberPagination
class BookView(ViewSetMixin, GenericAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
pagination_class = CommonPageNumberPagination
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page_list = self.paginate_queryset(queryset)
if page_list:
ser = self.get_serializer(page_list, many=True)
return self.get_paginated_response(data=ser.data)
ser = self.get_serializer(queryset, many=True)
return Response(ser.data)
LimitOffsetPagination
from .page import CommonLimitOffsetPagination
class BookView(ViewSetMixin, GenericAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
pagination_class = CommonLimitOffsetPagination
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page_list = self.paginate_queryset(queryset)
if page_list:
serializer = self.get_serializer(page_list, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
CursorPagination
from .page import CommonCursorPagination
class BookView(ViewSetMixin, GenericAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
pagination_class = CommonCursorPagination
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page_list = self.paginate_queryset(queryset)
if page_list is not None:
serializer = self.get_serializer(page_list, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
报错
1.先写个函数
from rest_framework.views import exception_handler
from rest_framework.response import Response
def common_exception(exc, context):
res = exception_handler(exc, context)
if not res:
return Response({'code': 999, 'msg': f'非drf错误,错误信息是:{str(exc)}'})
return Response({'code': 666, 'msg': f'这是drf错误,错误信息是:{res.data.get("detail")}'})
2.在配置文件中配置:
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'app01.exceptions.common_exception',
}