本文使用DRF框架來搭建介面后端框架,介面設計遵循restful定義
為什么要使用DRF框架,請參照轉載文章https://www.jianshu.com/p/ae36184e9925
前后端分離
如前后端用django+templates一套體系,templates模版里有很多只有django自由的屬性,如block、extends等,后端用的如頁面渲染render(request,'login.html',{'dabing':123123}),用此方法渲染必須帶一個頁面及字典或其他格式,這樣會導致后端與前端之間的規則要求很高,耦合度增加,如果哪天前端換了vue框架或者新開發了APP端,此時后端只能新開發一套介面才能滿足需求,
django實作restful api的方式
MTV–model view(業務) – 基于函式實作、基于類實作
讀資料:前端發出請求-》業務層-》從資料庫讀取資料(queryset表格)-》序列化 資料庫-》json
寫資料:json-》資料庫
基于函式
- 讀資料
從資料庫讀取資料格式是queryset物件,如果想讓它成為字典格式需models.Project.objects.values().多加個values,并轉換成串列LIST格式,最后在用JsonResponse轉換成json格式傳給前端,以下是基于函式實作(手寫)的restful api的代碼
@require_GET
def show(request):
"""
根據專案名稱檢索專案資訊
:param request:
:return:
# 回傳資料格式:
# 無資料:{"status_code":200,"cata":{"count":0,"Posts":null}}
# 有資料:{"status_code":200,"data":{"count":1,"posts":
# [{"name":"Shop","principal":"大餅", "environment":{"測驗環境":"http://dabing.com"}}]}}
"""
name = request.GET.get('name')
if name:
# 1,queryset型別的讀取方式與字典類似,但并非字典,它內部的值都是OBJECT物件,那么JSON是無法序列化物件的,
# 2,利用values()和values_list()方法,將queryset轉換成字典和串列形式的存盤方式,PS:這樣還不行,還有一步要做,
# 3,再將轉換完的queryset轉換成list串列, 注意:上面的轉換不是轉換成字典或串列,而是字典和串列的資料存盤形式,
# 4,這樣,通過JsonResponse就可以序列化了,重要一點:必須加入safe=False 引數,(因為咱們序列化的是一個串列)
items = models.Project.objects.values().filter(name__icontains=f'{name.strip()}')
else:
items = models.Project.objects.values().all()
items = list(items)
data = {'status_code': 200, 'data': {'Count': len(items), 'Posts': items}}
return JsonResponse(data, safe=False)
- 寫資料
將前端接收的json轉成python物件,通過save入庫
@require_POST
def add(request):
"""
資料格式:{"data":{"name":"ECShop","principal":"dabing", "environment":{"測驗環境":"http://dabing.com"}}}
:param request:
:return:
"""
try:
jsondata = json.loads(request.body)
project = models.Project()
project.name = jsonpath.jsonpath(jsondata, '$..name')[0]
project.environment = jsonpath.jsonpath(jsondata, '$..environment')[0]
project.principal = jsonpath.jsonpath(jsondata, '$..principal')[0]
if project.name and project.environment and project.principal:
project.save()
message = Message.Success
else:
message = Message.ArgumentInvalid
except JSONDecodeError:
message = Message.JsonDataError
except IntegrityError:
message = Message.DataDuplicate
except DataError:
message = Message.DataError
return HttpResponse(message)
基于類實作(djangorestframework)
- 繼承ApiView實作(默認方式)
重寫它的get、post等方法,此處的def get(self, request)里的request,與上圖如def add(request):不是一個request,此處是APIView封裝后的request,
寫一個view類,如ProjectAPIView(APIView)
from rest_framework.views import APIView
from api.views3.serializers import ProjectSerializers
from rest_framework.response import Response
from api.models import Project
class ProjectAPIView(APIView):
def get(self, request):
projects = Project.objects.all()
p = ProjectSerializers(projects, many=True)
return Response(p.data)
def post(self, request):
p = ProjectSerializers(data=request.data)
if p.is_valid():
p.save()
return Response(p.data)
else:
return Response(p.errors)
def delete(self, request, pk):
# pk = request.query_params('pk')
Project.objects.get(id=pk).delete()
return Response()
寫一個序列化類,在該類中指定model和序列化的欄位如ProjectSerializer(serializers.ModelSerializer):
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = models.Project
fields = '__all__'
2. 繼承ModelViewSet實作 之后都用這個框架來擴展
寫一個view類,例如,ProjectViewSetProject(viewsets.ModelViewSet)繼承ModelViewSet,會幫你實作create(), retrieve(), update()等操作
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `create()`, `retrieve()`, `update()`,
`partial_update()`, `destroy()` and `list()` actions.
"""
pass
from django.shortcuts import render
from rest_framework import viewsets
from api import serializers
from api import models
# Create your views here.
class ProjectViewSet(viewsets.ModelViewSet):
#指定資料集,是在這個資料集范圍內做序列化
queryset = models.Project.objects.all()
#指定所需序列化的類
serializer_class = serializers.ProjectSerializers
創建序列化類
from rest_framework import serializers
from api import models
class ProjectSerializers(serializers.ModelSerializer):
class Meta:
# 指定那個model里的表做序列化
model = models.Project
# 所要序列化的欄位,'__all__'是全部欄位
# fields = ('id','name')
fields = '__all__'
配置路由
from django.urls import path,include
from rest_framework import routers
from api import views
# 創建路由
router = routers.DefaultRouter()
# 注冊路由,只要后綴是project,會找視圖ProjectViewSet里的方法
router.register('project', viewset=views.ProjectViewSet)
urlpatterns = [
# 只要8000埠后帶api/會掃router里所注冊的路由地址
path('api/', include(router.urls)),
]
setting增加rest_framework
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'api',
'rest_framework',
]
以上把繼承ModelViewSet的框架已經搭建好,已經可以實作基本的增刪改查操作,通過請求資源型別來決定介面的操作,URL沒變,變的只是資料,遵循restful api規范,非常簡單!
呼叫方式:
查詢:http://ip:8000/project 請求方式:get 回傳:json 回傳格式默認是串列格式,因為可能會有多條資料
http://ip:8000/project/1 請求方式:get 回傳:json 查詢某一條記錄,查詢、修改、洗掉都類似



后續會增加過濾、重寫create(),retrieve(),update()`、定制錯誤格式、定制回傳報文等,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/250233.html
標籤:python
