欢迎来到Louis的博客

人生三从境界:昨夜西风凋碧树,独上高楼,望尽天涯路。 衣带渐宽终不悔,为伊消得人憔悴。 众里寻他千百度,蓦然回首,那人却在灯火阑珊处。
扩大
缩小

02-序列化组件的使用及接口设计-下

一.使用ModelViewSet和ViewSets视图集实现简单的CRUE

 项目结构

├── __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
View Code

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

 

posted on 2018-12-08 11:43  Louiszj  阅读(95)  评论(0编辑  收藏  举报

导航