rest下的urldjango
url惟一表明資源,http請求方式來區分用戶行爲編程
url的設計規範json
GET: 127.0.0.1:9001/books/ # 獲取全部數據session
GET: 127.0.0.1:9001/books/{id} # 獲取單條數據app
POST: 127.0.0.1:9001/books/ # 增長數據ide
DELETE: 127.0.0.1:9001/books/{id} # 刪除數據模塊化
PUT: 127.0.0.1:9001/books/{id} # 修改數據post
數據響應規範優化
GET: 127.0.0.1:9001/books/ # 返回[{}, {}, {}]url
GET: 127.0.0.1:9001/books/{id} # {} 單條數據
POST: 127.0.0.1:9001/books/ # {} 添加成功的數據
DELETE: 127.0.0.1:9001/books/{id} # "" 返回空
PUT: 127.0.0.1:9001/books/{id} # {} 更新後完整的數據
錯誤處理
{ "error": "message" }
解析器組件是用來解析用戶請求的數據的(application/json), content-type
必須繼承APIView
request.data觸發解析
APIView的使用
rest_framework是一個app須要在settings裏設置
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', ]
pip install djangorestframework
from rest_framework.views import APIView
class LoginView(APIView):
def get(self, request):
pass
from django.serializers import serialize # 引入 origin_data = Book.objects.all() serialized_data = serialize("json", origin_data)
from rest_framework import serializers #引入
建立一個序列化類
class BookSerializer(serializers.ModelSerializer): class Meta: model = Book # model字段 fields = ('title', 'price', 'publish', 'authors', 'author_list', 'publish_name', 'publish_city' ) # 只需寫入不須要展現的字段 extra_kwargs = { 'publish': {'write_only': True}, 'authors': {'write_only': True} } # source爲自定義須要展現的信息 publish_name = serializers.CharField(max_length=32, read_only=True, source='publish.name') publish_city = serializers.CharField(max_length=32, read_only=True, source='publish.city') # 多對多字段須要本身手動獲取數據,SerializerMethodField() author_list = serializers.SerializerMethodField() def get_author_list(self, book_obj): # 拿到queryset開始循環 [{}, {}, {}, {}] authors = list() for author in book_obj.authors.all(): authors.append(author.name) return authors
開始序列化
get接口(查詢多條數據) & post接口
class BookView(APIView): def get(self, request): # 獲取queryset origin_data = Book.objects.all() # 開始序列化 serialized_data = BookSerializer(origin_data, many=True) return Response(serialized_data.data) def post(self, request): verified_data = BookSerializer(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)
get(查詢單條數據) & put接口 & delete接口
class BookFilterView(APIView): def get(self, request, nid): book_obj = Book.objects.get(pk=nid) serialized_data = BookSerializer(book_obj, many=False) return Response(serialized_data.data) def put(self, request, nid): book_obj = Book.objects.get(pk=nid) verified_data = BookSerializer(data=request.data, instance=book_obj) if verified_data.is_valid(): verified_data.save() return Response(verified_data.data) else: return Response(verified_data.errors) def delete(self, request, nid): book_obj = Book.objects.get(pk=nid).delete() return Response()
缺點:
serializers.Serializer沒法插入數據,只能本身實現create字段太多,不能自動序列化
導入mixin
from rest_framework.mixinx import ( ListModelMix, CreateModelMixin, DestroyModelMixin, UpdateModelMixin, RetrieveModelMixin ) from rest_framework.generics import GenericAPIView
定義序列化類
Class BookSerializer(serializers.ModelSerializer): class Meta: Book fields = () ...如上
由於使用模塊化編程,建議將定義的序列化類放在單獨的模塊中,再在view.py中導入
from .app_serializers import BookSerializer
定義視圖類
class BookView(ListModelMix, CreateModelMixin, GenericAPIView): # queryset和serializer_class是固定的寫法 queryset = Book.objects.all() serializer_class = BookSerializer def get(): return self.list() # 查詢多條 def post(): return self.create() class BookFilterView(RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin, GenericAPIView): queryset = Book.objects.all() serializer_class = BookSerializer def get(): return self.retrieve() # 查詢單條 def delete(): return self.destroy() def put(): return self.update()
注意:
查詢單挑數據的url須要給查詢的id進行正則分組
re_path(r'books/(?P<pk>\d+)/$, views.BookFilterView.as_view())
導入模塊
from rest_framework import generics
視圖類
class BookView(generics.ListCreateAPIView) queryset = Book.objects.all() serializer_class = BookSerializer class BookFilterView(generics.RetrieveUpdateDestroyAPIView): queryset = Book.objects.all() serializer_class = BookSerializer
導入模塊
from rest_framework.viewsets import ModelViewSet
設計url
re_path(r'books/$, views.BookView.as_view({ 'get': 'list', 'post': 'create' })), re_path(r'books/(?P<pk>\d+)/$', views.BookView.as_view({ 'get': 'retrieve', 'delete': 'destroy', 'put': 'update' }))
設計視圖類
class BookView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer