django rest_framework中的APIView


models.py

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.py

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.py

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_demo


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM