django rest_framework中的APIView

models.pygit

from django.db import models

# Create your models here.


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

views.pygithub

from django.shortcuts import render

from app01 import models
from rest_framework import serializers
from rest_framework.response import Response
from rest_framework.views import APIView

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中的別名 url中須要添加別名name="publisher_detail"
        lookup_field="publisher_id", #關聯字段的字段名
        lookup_url_kwarg="pk",
    )
    # 默認一對多,多對多顯示主鍵,能夠自定義顯示字段爲name和其餘字段, 能夠不加就顯示所有  publisher用自定義的話post請求要重寫create方法
    # publisher = serializers.CharField(source="publisher.name")#一對多能夠用 自定義字段
    # 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"]["pk"])
        book.authors.add(*validated_data["authors"])
        return book

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

class PublisherView(APIView):

    #獲取全部出版社
    def get(self,request):

        pub_list = models.Publisher.objects.all()
        pub_ser = PublisherModelSerializer(pub_list,many=True) #若是序列化的是querset多個,就要用many=true,若是是單個對象,就不用
        return Response(pub_ser.data)     #提交出版社
    def post(self,request):
        print(request._request.body)
        print(request._request.POST)
        print("==========")
        print(request.data)


        pub_ser = PublisherModelSerializer(data=request.data)
        if pub_ser.is_valid():
            print(pub_ser.validated_data)
            pub_ser.save()
            return Response(pub_ser.data)
        else:
            return Response(pub_ser.errors)

class PublisherDetailView(APIView):
    #查看某個出版社
    def get(self,request,pk):
        pub_obj = models.Publisher.objects.filter(pk=pk).first()
        pub_ser = PublisherModelSerializer(pub_obj)
        return Response(pub_ser.data)
    #更新某個出版社 提交的時候id能夠不寫,其餘字段都不能少,不然報錯
    def put(self,request,pk):
        pub_obj = models.Publisher.objects.filter(pk=pk).first()
        pub_ser = PublisherModelSerializer(pub_obj,data=request.data)
        if pub_ser.is_valid():
            pub_ser.save()
            return Response(pub_ser.data)
        else:
            return Response(pub_ser.errors)
    #刪除某個出版社
    def delete(self,request,pk):
        models.Publisher.objects.filter(pk=pk).delete()
        return Response()

class BookView(APIView):

    def get(self,request):
        #http://127.0.0.1:8000/books/?a=1&b=2
        print(request._request.body) #b''  request._request.body區的是請求體的數據,GET沒有請求體爲空
        print(request._request.GET)  #<QueryDict: {'a': ['1'], 'b': ['2']}>#取到的是url中的數據

        book_list = models.Book.objects.all()
        book_ser = BookModelSerializer(book_list,many=True,context={"request": request})  #若是有超連接的話要加context={"request":request}
        return Response(book_ser.data)

    def post(self,request):
        print(request.data)
        book_ser = BookModelSerializer(data=request.data)
        print(book_ser)
        print("========")
        print(book_ser.publisher)
        if book_ser.is_valid():
            print(book_ser.validated_data)
            book_ser.save()
            return Response(book_ser.data)
        else:
            return Response(book_ser.errors)

class BookDetailView(APIView):

    def get(self,request,pk):
        book_obj = models.Book.objects.filter(pk=pk).first()
        book_ser = BookModelSerializer(book_obj,context={"request":request}) #若是有超連接的話要加context={"request":request}
        return Response(book_ser.data)

    def put(self,request,pk):
        book_obj = models.Book.objects.filter(pk=pk).first()
        book_ser = BookModelSerializer(book_obj,data=request.data)
        if book_ser.is_valid():
            book_ser.save()
            return Response(book_ser.data)
        else:
            return Response(book_ser.errors)

    def delete(self,request,pk):
        models.Book.objects.filter(pk=pk).delete()
        return Response()

urls.pydjango

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

urlpatterns = [
    url(r'^admin/', admin.site.urls),

    url(r'^publisher/$', views.PublisherView.as_view()),
    # url(r'^publisher/(\d+)/$', views.PublisherDetailView.as_view()), #不加超連接
    url(r'^publisher/(?P<pk>\d+)/', views.PublisherDetailView.as_view(), name="publisher_detail"), #加超連接
    #執行流程PublisherDetailView是一個類,調用as_view()方法返回值view,其實是執行APIView的父類(View)中as_view()中的view,
    #view的執行其實是dispatch方法的執行,dispatch返回什麼view就返回什麼,APIView中有dispatch方法,執行APIView中的dispatch
    #dispatch中的handle經過getattr找到對應PublisherDetailView中的get.post,put,delete方法


    url(r'^books/$', views.BookView.as_view()),
    url(r'^books/(?P<pk>\d+)/$', views.BookDetailView.as_view()),
]

 項目地址:https://github.com/CH-chen/APIView_demoapp

相關文章
相關標籤/搜索