1. 程式人生 > >rest-framework之檢視元件

rest-framework之檢視元件

寫一個出版社的增刪查改resful介面

# models.py模板層
from django.db import models


class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.CharField(max_length=32)
    publish_date = models.DateField()

    publish = models.ForeignKey(to='
Publish',to_field='nid',on_delete=models.CASCADE) authors = models.ManyToManyField(to='Author') def __str__(self): return self.name class Author(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) age = models.IntegerField() author_detail
= models.OneToOneField(to='AuthorDetail', to_field='nid', unique=True, on_delete=models.CASCADE) class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True) telephone = models.BigIntegerField() birthday = models.DateField() addr = models.CharField(max_length=64) class
Publish(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) city = models.CharField(max_length=32) email = models.EmailField() def __str__(self): return self.name def test(self): return self.email
model.py 模板層

#url 路由層

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

# 生成一個router物件
router = routers.DefaultRouter()
# 需要傳兩個引數,第一個引數就是匹配的路徑,第二個引數,是檢視類
router.register('publish', views.PublishView)
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # url(r'^publish/',views.PublishView.as_view() ),
    # url(r'^publish/(?P<pk>\d+)',views.PublishDetailView.as_view() ),

    # url(r'^publish/$', views.PublishView.as_view({'get': 'list', 'post': 'create'})),
    # url(r'^publish/(?P<pk>\d+)', views.PublishView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
    url(r'^test1/$', views.TestAll.as_view({'get': 'test'})),
    # url(r'^test2/$', views.TestAll.as_view({'get': 'test2'})),
    # url(r'^test3/$', views.TestAll.as_view({'get': 'test3'})),
    
    # 不會使用這種方法的
    url('', include(router.urls)),
]



路由控制
        三種:
            -一種基本路由:url(r'^publish/$', views.PublishView.as_view()),
            -半自動路徑:views.PublishView.as_view({'get': 'list', 'post': 'create'}))
                -必須繼承:ViewSetMixin
                -繼承ViewSetMixin的先後順序
            -全自動路由:(基本不用)
                -from rest_framework import routers
                # 生成一個router物件
                router=routers.DefaultRouter()
                # 需要傳兩個引數,第一個引數就是匹配的路徑,第二個引數,是檢視類
                router.register('publish',views.PublishView)
                
                
                url('', include(router.urls)),
                #自動生成四個路由(PublishView必須繼承ModelViewSet)
url 路由層

#MySer 序列化元件

from rest_framework import serializers
from app01 import models


class AuthorSerializers(serializers.Serializer):
    nid = serializers.CharField()
    name = serializers.CharField()
    age = serializers.CharField()


class PublishSerializers(serializers.ModelSerializer):
    class Meta:
        model = models.Publish
        fields = '__all__'
View Code

基本檢視

最原始的
from django.shortcuts import render,HttpResponse
from rest_framework.views import APIView
from app01 import models
from app01.MySer import AuthorSerializers, PublishSerializers
from django.http import JsonResponse

class PublishView(APIView):

    def get(self, request):
        publish_list = Publish.objects.all()
        bs = PublishSerializers(publish_list, many=True)

        return JsonResponse(bs.data,safe=False)

    def post(self, request):
        # 新增一條資料
        print(request.data)

        bs = PublishSerializers(data=request.data)
        if bs.is_valid():
            bs.save()  # 生成記錄
            return JsonResponse(bs.data,safe=False)
        else:

            return JsonResponse(bs.errors,safe=False)


class PublishDetailView(APIView):
    def get(self, request, pk):
        publish_obj = Publish.objects.filter(pk=pk).first()
        bs = PublishSerializers(publish_obj, many=False)
        return JsonResponse(bs.data,safe=False)

    def put(self, request, pk):
        publish_obj = Publish.objects.filter(pk=pk).first()

        bs = PublishSerializers(data=request.data, instance=publish_obj)
        if bs.is_valid():
            bs.save()  # update
            return JsonResponse(bs.data)
        else:
            return JsonResponse(bs.errors)

    def delete(self, request, pk):
        Publish.objects.filter(pk=pk).delete()

        return JsonResponse("")
普通檢視層

 

1
第一種方案

class List:
    def list(self,request):
        queryset = self.queryset
        bs = self.serializers(queryset, many=True)
        return JsonResponse(bs.data,safe=False)

class Create:
    def create(self,request):
        print(request.data)

        bs = PublishSerializers(data=request.data)
        if bs.is_valid():
            bs.save()  # 生成記錄
            return JsonResponse(bs.data,safe=False)
        else:

            return JsonResponse(bs.errors,safe=False)
class PublishView(APIView,List,Create):
    queryset=Publish.objects.all()
    serializers=PublishSerializers
    def get(self, request):
        return self.list(request)

    def post(self, request):
        # 新增一條資料
        return self.create(request)

class BookView(APIView,List,Create):
    queryset=Book.objects.all()
    serializers=BookSerializer
    def get(self, request):
        return self.list(request)

    def post(self, request):
        return self.create(request)
.第一種方案 — 檢視層

 

第二種:ListCreateAPIView 繼承了GenericAPIView, ListModelMixin, CreateModelMixin

2 .第二種方案 :drf提供的封裝的類——檢視層

 

第三種:路由:url(r'^publish/$', views.PublishView.as_view({'get': 'list', 'post': 'create'})),
url(r'^publish/(?P<pk>\d+)', views.PublishView.as_view({'get': 'retrieve', 'put': 'update','delete':'destroy'})),

3.
from rest_framework.generics import ListCreateAPIView, ListAPIView, RetrieveUpdateDestroyAPIView


from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, \
    DestroyModelMixin
from rest_framework.generics import GenericAPIView

class PublishView(GenericAPIView, ListModelMixin, CreateModelMixin):
class PublishView(ListCreateAPIView):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializers


class PublishDetailView(RetrieveUpdateDestroyAPIView):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializers
第三種方案 ——檢視層

 

from rest_framework.views import  APIView
from rest_framework.viewsets import ModelViewSet
from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
class PublishView(ModelViewSet):
    # renderer_classes=[JSONRenderer,BrowsableAPIRenderer]
    queryset = Publish.objects.all()
    serializer_class = PublishSerializers
第四種方案:不建議使用

終極版本:

建議用魔法類ViewSetMixin
最終應該使用的方案:ViewSetMixin 它有什麼作用?用了它之後,檢視類中不需要寫get,post,put方法了,自己定義方法就可以了
讓請求方法對應到自己定義的方法上,然後再配置路由

# from day100 import settings
# settings 就是專案的配置檔案
from django.conf import settings
class BookView(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
from rest_framework.response import Response
# 建議用魔法類ViewSetMixin

rom rest_framework.viewsets import ViewSetMixin # 注意先後順序,ViewSetMixin寫在前面 class TestAll(ViewSetMixin,APIView): def test(self,request): print(settings.DEBUG) return HttpResponse('test') def test2(self, request): return HttpResponse('test2') def test3(self, request): return HttpResponse('test3')