models.py

from django.db import models

class UserInfo(models.Model):
    name = models.CharField(max_length=32)
    pwd = models.CharField(max_length=32)

class UserToken(models.Model):
    token = models.CharField(max_length=128)
    userinfo = models.OneToOneField(to="UserInfo")


class Publisher(models.Model):
    name = models.CharField(max_length=64)
    email = models.EmailField()

    def __str__(self):
        return self.name

class Book(models.Model):
    title=models.CharField(max_length=64)
    price = models.IntegerField()
    pub_date = models.DateField()
    publisher=models.ForeignKey(to='Publisher')
    authors = models.ManyToManyField(to="Author")
    def __str__(self):
        return self.title

class Author(models.Model):
    name = models.CharField(max_length=48)
    age = models.IntegerField(default=2)
    def __str__(self):
        return self.name

seria.py

from app01 import models
from rest_framework import serializers

class PublisherModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Publisher
        fields = "__all__"

class BookModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = "__all__"

        # 以上是默认的
        # 显示超链接
    publisher = serializers.HyperlinkedIdentityField(
        view_name="publisher_detail",  # url中的别名
        lookup_field="publisher_id", #关联字段的字段名
        lookup_url_kwarg="pk",
    )
    # 默认一对多,多对多显示主键,可以自定义显示字段为name和其他字段, 可以不加就显示全部  publisher用自定义的话post请求要重写create方法
    # publisher = serializers.CharField(source="publisher.name",read_only=True)#一对多可以用 自定义字段
    # authors = serializers.CharField(source="authors.all") #多对多不好用
    # 多对多自定义显示字段用下面这个,默认显示主键
    # authors =serializers.SerializerMethodField() 自定义字段
    # def get_authors(self,obj):
    #     temp = []
    #     for obj in obj.authors.all():
    #         temp.append(obj.name)
    #         print(temp)
    #     return temp
    # 自定义显示字段 用自定义的话post请求要重写create方法,不自定义用默认的就不需要create方法
    # def create(self,validated_data):
    #     print("validated_data",validated_data)
    #     book = models.Book.objects.create(title=validated_data["title"],price=validated_data["price"],pub_date=validated_data["pub_date"],publisher_id=validated_data["publisher"].split("/")[-2])
    #     book.authors.add(*validated_data["authors"])
    #     return book

class AuthorModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Author
        fields = "__all__"

seria2.py

from app01 import models
from rest_framework import serializers


class PublisherModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Publisher
        fields = "__all__"

class BookModelSerializer(serializers.ModelSerializer):

    # 默认一对多,多对多显示主键,可以自定义显示字段为name和其他字段, 可以不加就显示全部  publisher用自定义的话post请求要重写create方法
    publisher = serializers.CharField(source="publisher.pk",read_only=True)#一对多可以用 自定义字段不用加read_only=True
    # authors = serializers.CharField(source="authors.all") #多对多不好用
    # 多对多自定义显示字段用下面这个,默认显示主键
    # authors =serializers.SerializerMethodField() #自定义字段
    # def get_author(self,obj):
    #     temp = []
    #     for obj in obj.authors.all():
    #         temp.append(obj.name)
    #         print(temp)
    #     return temp
    # 自定义显示字段 用自定义的话post请求要重写create方法,不自定义用默认的就不需要create方法

    class Meta:
        model = models.Book
        fields = "__all__"
        read_only_fields = ["id"]
    def create(self,validated_data):
        print("validated_data",validated_data)

        book = models.Book.objects.create(title=validated_data["title"],price=validated_data["price"],pub_date=validated_data["pub_date"],publisher_id=validated_data["publisher"]["pk"])
        book.authors.add(*validated_data["authors"])
        return book

class AuthorModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Author
        fields = "__all__"

views.py

from django.shortcuts import render
from app01 import models
from app01 import seria

from rest_framework import mixins
from rest_framework import generics

#*********第一种继承方法
class PublsherMixView(mixins.ListModelMixin,
                      mixins.CreateModelMixin,
                      generics.GenericAPIView):

    queryset = models.Publisher.objects.all()
    serializer_class = seria.PublisherModelSerializer

    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 PublisherDetailMix(mixins.RetrieveModelMixin,
                         mixins.UpdateModelMixin,
                         mixins.DestroyModelMixin,
                         generics.GenericAPIView):

    queryset = models.Publisher.objects.all()
    serializer_class = seria.PublisherModelSerializer

    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)

class BookMixView(mixins.ListModelMixin,
                      mixins.CreateModelMixin,
                      generics.GenericAPIView):

    queryset = models.Book.objects.all()
    serializer_class = seria.BookModelSerializer

    def get(self,request,*args,**kwargs):
        return self.list(request,*args,**kwargs)

    def post(self,request,*args,**kwargs):
        print("=======")
        print(request.data)
        return self.create(request,request.data,*args,**kwargs)

class BookDetailMix(mixins.RetrieveModelMixin,
                         mixins.UpdateModelMixin,
                         mixins.DestroyModelMixin,
                         generics.GenericAPIView):

    queryset = models.Book.objects.all()
    serializer_class = seria.BookModelSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        print("$$$$$$$")
        print(request.data)
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

##***************第二种继承方法

from app01 import seria2
from rest_framework import mixins
from rest_framework import generics

class PublsherGenView(generics.ListCreateAPIView):

    queryset = models.Publisher.objects.all()
    serializer_class = seria2.PublisherModelSerializer

class PublisherDetailGen(generics.RetrieveUpdateDestroyAPIView):

    queryset = models.Publisher.objects.all()
    serializer_class = seria2.PublisherModelSerializer

class BookGenView(generics.ListCreateAPIView):

    queryset = models.Book.objects.all()
    serializer_class = seria2.BookModelSerializer

class BookDetailGen(generics.RetrieveUpdateDestroyAPIView):

    queryset = models.Book.objects.all()
    serializer_class = seria2.BookModelSerializer


#####*********第三种********viewsets.ModelViewSet**
from rest_framework import viewsets
class BookViewSet(viewsets.ModelViewSet):
    queryset = models.Book.objects.all()
    serializer_class = seria2.BookModelSerializer

urls.py

from django.conf.urls import url,include
from django.contrib import admin
from app01 import views

#第三种url简写
#简写第一步
from rest_framework import routers

routers = routers.DefaultRouter()
routers.register(r"books001",views.BookViewSet) #books001为URL前缀



urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^publisher/$', views.PublsherMixView.as_view()),
    # url(r'^publisher/(\d+)/$', views.PublisherDetailView.as_view()), #不加超链接
    url(r'^publisher/(?P<pk>\d+)/', views.PublisherDetailMix.as_view(), name="publisher_detail"),


    url(r'^book/$', views.BookMixView.as_view()),
    url(r'^book/(?P<pk>\d+)/$', views.BookDetailMix.as_view()),

    ##**********第二种*******
    url(r'^publishers/$', views.PublsherGenView.as_view()),
    url(r'^publishers/(?P<pk>\d+)/$', views.PublisherDetailGen.as_view()),

    url(r'^books/$', views.BookGenView.as_view(),name="book_list"),
    url(r'^books/(?P<pk>\d+)/$', views.BookDetailGen.as_view(),name="book_detail"),

    ##*****第三种 这种还可以简写
    # url(r'^books1/$', views.BookViewSet.as_view({"get":"list","post":"create"}),name="book_list"),
    # url(r'^books1/(?P<pk>\d+)/$', views.BookViewSet.as_view({
    #             'get': 'retrieve',
    #             'put': 'update',
    #             'patch': 'partial_update',
    #             'delete': 'destroy'
    #         }),name="book_detail"),


    ##简写第二步
    url(r'^', include(routers.urls)),


]

#简写默认生成如下url
# # ^books001/$ [name='book-list']
# ^ ^books001\.(?P<format>[a-z0-9]+)/?$ [name='book-list']
# ^ ^books001/(?P<pk>[^/.]+)/$ [name='book-detail']
# ^ ^books001/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='book-detail']

 项目地址:https://github.com/CH-chen/mixns_demo