drf 代码流程总结
一、基于APIView+Response写五个接口
view.py
from django.shortcuts import render
from rest_framework.views import APIView
from .serializer import BookSerializer, PublishSerializer
# Create your views here.
from rest_framework.response import Response
from rest_framework.views import APIView
from .models import Book, Publish
class BookView(APIView):
# 查询所有信息
def get(self, request):
book_list = Book.objects.all()
ser = BookSerializer(instance=book_list, many=True)
return Response(ser.data)
# 新增一条信息
def post(self, request):
ser = BookSerializer(data=request.data)
if ser.is_valid():
ser.save()
return Response(ser.data)
else:
return Response(ser.errors)
class BookDetailView(APIView):
# 查询单条信息
def get(self, request, pk):
book = Book.objects.filter(pk=pk).first()
ser = BookSerializer(instance=book)
return Response(ser.data)
# 修改信息
def put(self, request, pk):
book = Book.objects.filter(pk=pk).first()
ser = BookSerializer(instance=book, data=request.data)
if ser.is_valid():
ser.save()
return Response(ser.data)
else:
return Response(ser.errors)
# 删除信息
def delete(self,request,pk):
Book.objects.filter(pk=pk).first()
return Response()
models.py
from django.db import models
# Create your models here.
from rest_framework.views import APIView
class Book(models.Model):
name = models.CharField(max_length=32)
price = models.CharField(max_length=32)
publish = models.CharField(max_length=32)
class Publish(models.Model):
name = models.CharField(max_length=32)
city = models.CharField(max_length=32)
serializer.py
from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.Serializer):
name = serializers.CharField()
price = serializers.CharField()
publish = serializers.CharField()
# 重写create方法
def create(self, validated_data):
res = Book.objects.create(**validated_data)
return res
def update(self, instance, validated_data):
instance.name = validated_data.get('name')
instance.price = validated_data.get('price')
instance.publish = validated_data.get('publish')
instance.save()
return instance
class PublishSerializer(serializers.Serializer):
name = serializers.CharField()
city = serializers.CharField()
urls.py
path('books/',views.BookView.as_view()),
path('books/<int:pk>/', views.BookDetailView.as_view())
二、序列化类高级用法之定制序列化字段
第一种实现
models.py
from django.db import models
# Create your models here.
from django.db import models
class Book(models.Model):
name = models.CharField(max_length=32,verbose_name='书本姓名')
price = models.DecimalField(max_digits=5, decimal_places=2,verbose_name='价格')
publish_date = models.DateField(null=True,verbose_name='出版日期')
publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
authors = models.ManyToManyField(to='Author')
def __str__(self):
return self.name
# 写了个方法,可以包装成数据属性,也可以不包
def publish_de(self):
return {'name': self.publish.name, 'city': self.publish.city, 'email': self.publish.email}
def author_li(self):
res_list = []
for author in self.authors.all():
res_list.append({'id': author.id, 'name': author.name, 'age': author.age})
return res_list
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE)
def __str__(self):
return self.name
class AuthorDetail(models.Model):
telephone = models.BigIntegerField()
birthday = models.DateField()
addr = models.CharField(max_length=64)
class Publish(models.Model):
name = models.CharField(max_length=32)
city = models.CharField(max_length=32)
email = models.EmailField()
# def __str__(self):
# return self.name
admin.py
from django.contrib import admin
from .models import *
# Register your models here.
admin.site.register(Book)
admin.site.register(Author)
admin.site.register(AuthorDetail)
admin.site.register(Publish)
views.py
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from .serializer import BookSerializer
from .models import Book
# Create your views here.
class BookView(APIView):
def get(self, request):
book_list = Book.objects.all()
ser = BookSerializer(instance=book_list, many=True)
return Response(ser.data)
serializer.py
from rest_framework import serializers
class BookSerializer(serializers.Serializer):
name = serializers.CharField(max_length=32, min_length=3)
price = serializers.IntegerField(max_value=32, min_value=6)
publish_date = serializers.DateField()
publish = serializers.SerializerMethodField()
def get_publish(self, obj):
return {'name': obj.publish.name, 'city': obj.publish.city, 'email': obj.publish.email}
2. 在表模型中写
models.py中
# 表模型中
class Book(models.Model):
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5, decimal_places=2)
publish_date = models.DateField(null=True)
publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
authors = models.ManyToManyField(to='Author')
# 写了个方法,可以包装成数据属性,也可以不包
def publish_detail(self):
return {'name': self.publish.name, 'city': self.publish.city, 'email': self.publish.email}
def author_list(self):
res_list = []
for author in self.authors.all():
res_list.append({'id': author.id, 'name': author.name, 'age': author.age})
return res_list
# 序列化类中
class BookSerializer(serializers.Serializer):
name = serializers.CharField(max_length=8, min_length=3)
price = serializers.IntegerField(min_value=10, max_value=99)
publish_date = serializers.DateField()
# 方式二:在表模型中写方法
publish_detail = serializers.DictField(read_only=True)
# 练习,使用方式二实现,显示所有作者
author_list = serializers.ListField(read_only=True)
反序列化之数据校验
##### 反序列化字段校验
from rest_framework.exceptions import ValidationError
class BookModelSerializer(serializers.ModelSerializer):
name=serializers.CharField(max_length=8,min_length=3)
class Meta:
model = Book
fields = ['name', 'price', 'publish_date', 'publish', 'authors', 'publish_de', 'author_li'] # 列表中有什么,就是序列化哪个字段
extra_kwargs = {
'name': {'max_length': 80, 'min_length': 3, 'error_messages': {'min_length': "太短了"}},
'price': {'max_value': 100, 'min_value': 9},
'publish': {'write_only': True},
'authors': {'write_only': True},
}
# 给name字段加局部钩子,一定不要写在内部类中
def validate_name(self, name):
if name.startswith('sb'):
# 校验不通过,抛异常
raise ValidationError('不能以sb卡头')
else:
return name
def validate_price(self, price):
if price == 44:
raise ValidationError('不能是44,没有为什么')
else:
return price
def validate(self, attrs):
if attrs.get('name') == attrs.get('publish_date'):
raise ValidationError('名字不能等于日期')
else:
return attrs
使用GenericAPIView写出book的5个接口
from rest_framework.generics import GenericAPIView
class BookView(GenericAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
def get(self, request):
book_list = self.get_queryset()
ser = self.get_serializer(instance=book_list, many=True)
return Response(ser.data)
def post(self, request):
ser = self.get_serializer(data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'msg': "新增成功"}, status=201)
else:
return Response({'code': 101, 'msg': ser.errors})
class BookDetailView(GenericAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
def get(self, request, pk):
book = self.get_object()
ser = self.get_serializer(instance=book)
return Response(ser.data)
def put(self, request, pk):
book = self.get_object()
ser = self.get_serializer(instance=book,data=request.data)
if ser.is_valid():
ser.save()
return Response({'code':100,'msg':"修改成功"},status=201)
else:
return Response({'code':101,'msg':ser.errors})
def delete(self,request,pk):
self.get_queryset().filter(pk=pk).delete()
return Response('')
五个扩展类
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import RetrieveModelMixin, CreateModelMixin, UpdateModelMixin, DestroyModelMixin, \
ListModelMixin
class UserView(GenericAPIView, ListModelMixin, CreateModelMixin):
queryset = User.objects.all()
serializer_class = UserSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
class UserDetailView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
queryset = User.objects.all()
serializer_class = UserSerializer
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
九个视图子类
from rest_framework.generics import ListAPIView, CreateAPIView, RetrieveAPIView, DestroyAPIView, UpdateAPIView
from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView, RetrieveUpdateAPIView, \
RetrieveDestroyAPIView
class UserView(ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
class UserDetailView(RetrieveUpdateDestroyAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
视图集
视图类
from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet
class UserView(ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
路由
path('user/', views.UserView.as_view({'get': 'list', 'post': 'create'})),
path('user/<int:pk>', views.UserView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
自动生成路由
from django.contrib import admin
from django.urls import path, include # include是干分发路由用的
from app01 import views
# 自动生成路由
# drf提供了两个路由类,以后继承了ViewSetMixin及其子类的视图类,就可以使用这两个路由类来自动生成路由,(也就是不用自己写了,让他自动去生成路由)
# 使用步骤
# 第一步:导入路由类
from rest_framework.routers import SimpleRouter, DefaultRouter
# 第二步:实例化得到对象
router = SimpleRouter()
# router = DefaultRouter() 就多一个根路径,和SimpleRouter几乎没差别,平时用的还是SimpleRouter多一些
# 第三步:注册路由(可以注册多个)
# 注册需要传三个参数 {第一个参数:路径 第二个参数:视图类(继承了ViewSetMixin及其子类的视图类) 第三个参数:别名,可以不写(默认以路径作为别名)}
router.register('books', views.BookView, 'books')
router.register('publish', views.PublishView, 'publish')
router.register('user', views.UserView, 'user')
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(router.urls)),
# path('user/', views.UserView.as_view({'get':'login'})),
# path('books/', views.BookView.as_view({'get': 'list', 'post': 'create'})),
# path('books/<int:pk>', views.BookView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
]
# 第四步:把自动生成的路由添加到urlpatterns中
# 方式一:
# urlpatterns+=router.urls
# 方式二,使用include添加
# path('', include(router.urls)),

浙公网安备 33010602011771号