02-序列化组件的使用及接口设计-下
一.使用ModelViewSet和ViewSets视图集实现简单的CRUE
项目结构
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
├── __init__.py ├── __pycache__ │ ├── __init__.cpython-37.pyc │ ├── admin.cpython-37.pyc │ ├── api_serializers.cpython-37.pyc │ ├── apps.cpython-37.pyc │ ├── models.cpython-37.pyc │ └── urls.cpython-37.pyc ├── admin.py ├── api_serializers.py ├── apps.py ├── migrations │ ├── 0001_initial.py │ ├── __init__.py │ └── __pycache__ │ ├── 0001_initial.cpython-37.pyc │ └── __init__.cpython-37.pyc ├── models.py ├── tests.py ├── urls.py ├── views │ ├── ApiViews.py │ ├── GenericsViews.py │ ├── MixinViews.py │ ├── ModelViewSet.py │ ├── __init__.py │ └── __pycache__ │ ├── ApiViews.cpython-37.pyc │ ├── GenericsViews.cpython-37.pyc │ ├── MixinViews.cpython-37.pyc │ ├── ModelViewSet.cpython-37.pyc │ └── __init__.cpython-37.pyc └── views.py
api_serializers.py
from rest_framework import serializers from app01.models import Book class BookSerialize(serializers.ModelSerializer): class Meta: model = Book fields = ('id', 'title', 'price', 'authors', 'publish', 'authors_list', 'publish_name', 'publish_city' ) # 附加关键字参数 extra_kwargs = { 'publish': {'write_only': True}, 'authors': {'write_only': True} } # 只读字段 read_only_fields = ('publish_name', 'publish_city') # 显式定义字段 publish_name = serializers.CharField(max_length=32, source='publish.name') publish_city = serializers.CharField(max_length=32, source='publish.city') # 多对多字段需要定义get_<field_name>方法处理数据 authors_list = serializers.SerializerMethodField() def get_authors_list(self, book_obj): authors = [author.name for author in book_obj.authors.all()] return authors
models.py
from django.db import models # Create your models here. from django.db import models # Create your models here. class Book(models.Model): """ 书籍表 """ nid = models.AutoField(primary_key=True) title = models.CharField(max_length=32) price = models.DecimalField(max_digits=6, decimal_places=2) publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE) authors = models.ManyToManyField(to='Author') def __str__(self): return self.title class Author(models.Model): """ 作者表 """ nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) age = models.IntegerField() def __str__(self): return self.name class Publish(models.Model): """ 出版社表 """ nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) city = models.CharField(max_length=120) email = models.EmailField() def __str__(self): return self.name
urls.py
from django.urls import path, re_path from app01.views import (ApiViews, MixinViews, GenericsViews, ModelViewSet) urlpatterns = [ # APIView path('book1/', ApiViews.BookView.as_view()), re_path('book1/(\d+)/$', ApiViews.BookFilterView.as_view()), # MixinViews path('book2/', MixinViews.BookView.as_view()),
# 注意:单条数据操作的url是这样的:re_path(r'books/(?P<pk>\d+)/$, views.BookFilterView.as_view()) re_path('book2/(?P<pk>\d+)/$', MixinViews.BookFilterView.as_view()), # GenericViews path('book3/', GenericsViews.BookView.as_view()), re_path(r'book3/(?P<pk>\d+)/$', GenericsViews.BookFilterView.as_view()), # ModelViewSet path('book4/', ModelViewSet.BookView.as_view({ 'get': 'list', 'post': 'create' })), re_path(r'book4/(?P<pk>\d+)/$', ModelViewSet.BookView.as_view({ 'get': 'retrieve', 'put':'update', 'delete':'destrory' })) ]
ApiViews.py
from django.shortcuts import render from rest_framework.views import APIView from rest_framework.response import Response from app01.models import Book, Author from app01.api_serializers import BookSerialize # Create your views here. class BookView(APIView): def get(self, request): book_obj = Book.objects.all() serialized_data = BookSerialize(book_obj, many=True) return Response(serialized_data.data) def post(self, request): verified_data = BookSerialize(data=request.data) if verified_data.is_valid(): book = verified_data.save() authors = Author.objects.filter(nid__in=request.data['authors']) book.authors.add(*authors) return Response(verified_data.data) else: return Response(verified_data.errors) class BookFilterView(APIView): def get(self, request, nid): book_obj = Book.objects.filter(pk=nid).first() serialized_data = BookSerialize(book_obj, many=False) return Response(serialized_data.data) def put(self, request, nid): book_obj = Book.objects.filter(pk=nid).first() verified_data = BookSerialize(data=request.data, instance=book_obj, many=False) if verified_data.is_valid(): verified_data.save() return Response(verified_data.data) else: return Response(verified_data.errors)
GenericsViews.py
from rest_framework import generics from app01.api_serializers import BookSerialize from app01.models import Book class BookView(generics.ListCreateAPIView): queryset = Book.objects.all() serializer_class = BookSerialize class BookFilterView(generics.RetrieveUpdateDestroyAPIView): queryset = Book.objects.all() serializer_class = BookSerialize
MixinViews.py
from rest_framework.mixins import (ListModelMixin, CreateModelMixin, UpdateModelMixin, DestroyModelMixin, RetrieveModelMixin ) from rest_framework.generics import GenericAPIView from app01.api_serializers import BookSerialize from app01.models import Book class BookView(ListModelMixin, CreateModelMixin, GenericAPIView): queryset = Book.objects.all() serializer_class = BookSerialize 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 BookFilterView(UpdateModelMixin, DestroyModelMixin, RetrieveModelMixin, GenericAPIView): queryset = Book.objects.all() serializer_class = BookSerialize def get(self, request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) def delete(self, request, *args, **kwargs): return self.delete(request, *args, **kwargs) def put(self, request, *args, **kwargs): return self.update(request, *args, **kwargs)
ModelViewSet.py
from rest_framework.viewsets import ModelViewSet from app01.api_serializers import BookSerialize from app01.models import Book class BookView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerialize