一、Django REST Framework, Django View & APIView
MTV模式实现前后端分离。Representational State Transfer 表现层状态转化。Representation 资源(Resource a specific info. on net.)具体呈现形式。ST 修改服务端的数据。修改数据 == POST请求。实现: 安装依赖 pip install djangorestframework / 序列化 / 视图装饰器 / 视图集
pip install djangorestframework
pip install httpie
python manage.py startapp rest_app
setting注册
path('rest_app/', include('rest_app.urls', namespace='rest')),
models //
from django.db import models
class Students(models.Model):
name = models.CharField(max_length=32, verbose_name="NAME")
age = models.IntegerField(verbose_name="AAAAGE")
gender = models.CharField(max_length=2, verbose_name="GENDER")
gpa = models.FloatField(verbose_name="BASIS")
class Meta:
verbose_name = "Students"
verbose_name_plural = verbose_name + 'S'
def __str__(self):
return self.name
@classmethod
def get_all(cls):
return cls.objects.all()
admin //
from django.contrib import admin
from rest_app.models import Students
admin.site.register(
Students
)
app下serializer.py //
from rest_framework import serializers
from rest_app.models import Students
class StudentSerializer(serializers.ModelSerializer): # 自定义一个用于序列化student模型的序列化类
class Meta:
model = Students
fields = (
"id",
"name",
"age",
"gender",
"gpa",
)
# 序列化:继承djangorestframework中的serialize。str(a dict), 是一个jason字符串。
views //
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_app.models import Students
from rest_app.serializer import StudentSerializer
@api_view(["GET"])
def students_view(request):
# 用不着render了,前端也不存在query set,所以需要序列化类
students = Students.get_all()
ser = StudentSerializer(students, many=True)
return Response(ser.data)
# 视图装饰器。能接收什么样的请求。api_view。
urls //
from django.urls import path
from .views import *
app_name = 'rest'
urlpatterns = [
path('stuview/', students_view, name="stuview"),
]
# 用httpie来检测。
http get http://127.0.0.1:8000/rest/stuview
or postman.
Django rest post请求 put delete请求
views //
@api_view(["GET", "POST"])
def students_view(request):
# 用不着render了,前端也不存在query set,所以需要序列化类
if request.method == "GET":
students = Students.get_all()
ser = StudentSerializer(students, many=True)
return Response(ser.data)
if request.method == "POST":
ser = StudentSerializer(data=request.data)
if ser.is_valid():
ser.save()
return Response(ser.data, status=status.HTTP_201_CREATED)
else:
return Response(status=status.HTTP_400_BAD_REQUEST)
# id是自增的,所以不创建也可。建了也白建。但其他关键字在创建时不可省略。
postman:
post raw json
@api_view(["GET", "PUT", "DELETE"])
def student_detail_view(request, sid):
try:
student = Students.get_one(sid)
except Students.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == "GET":
ser = StudentSerializer(student)
return Response(ser.data)
if request.method == "PUT":
ser = StudentSerializer(student, data=request.data)
if ser.is_valid():
ser.save()
return Response(ser.data)
else:
return Response(status=status.HTTP_400_BAD_REQUEST)
if request.method == "DELETE":
student.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
put 即使只修改一个字段也要写入所有字段
delete 不需要传,只需要send
二、Django REST 视图集
models //
class StudentsCla(models.Model): class_name = models.CharField(max_length=32, verbose_name="NAMECLA") mentor = models.CharField(max_length=32, verbose_name="HEADTEACHER") class Meta: verbose_name = "CLA" verbose_name_plural = verbose_name def __str__(self): return self.class_name @classmethod def get_all(cls): return cls.objects.all()
admin //
from django.contrib import admin from rest_app.models import Students, StudentsCla models = [ Students, StudentsCla ] admin.site.register(models)
serializer //
class StudentsClaSerializer(serializers.ModelSerializer): # 自定义一个用于序列化student模型的序列化类 class Meta: model = StudentsCla fields = ( "class_name", "mentor", )
views //
class ListStudentsClaViewSet(ModelViewSet): queryset = StudentsCla.get_all() # 使用模型视图集需要指定queryset的值和s_c serializer_class = StudentsClaSerializer pass
total urls //
from rest_framework import routers from rest_app.views import ListStudentsClaViewSet router = routers.DefaultRouter() router.register('student_class', ListStudentsClaViewSet)
path('', include(router.urls))
视图集是将一个视图函数转换成一个类,并继承ViewSet。结果的这个类即 类视图。
三、VIEW & API VIEW 类视图
常分三类。View类视图(django原生有的),APIView类视图(支持前后端分离),通用类视图。
View类视图:①继承View类,编写对应的请求方法,处理不同请求状态。②配置路由,使用as_view()。
演示:
python manage.py startapp view_app
注册
path('view/', include('view_app.urls', namespace="view")),
models //
class Stu(models.Model): name = models.CharField(max_length=32, verbose_name="name") gpa = models.CharField(verbose_name="gpa") @classmethod def get_all(cls): return cls.objects.all()
views //
class ListStuView(View): def get(self, request): stus = Stu.get_all() return render(self.request, "", locals()) def post(self, request): pass return render(self.request, "", locals()) class ListStuAPIView(APIView): def get(self, request): stus = Stu.get_all() return Response(status=status.HTTP_200_OK) def post(self, request): pass return render(self.request, "", locals()) def put(self, request): pass def delete(self, request): pass
sub urls //
urlpatterns = [ path('view/', ListStuView.as_view(), name="list"), ]
通用类视图
Django Restful
①操作所有的model。继承ListCreateAPIView类,并添加queryset和serializer_class两个类属性
②操作单个model。继承RetrieveUpdateDestroyAPIView类,并添加queryset和serializer_class两个类属性
总路由 //
path('view/', include('view_app.urls', namespace="view")),
models //
from django.db import models class Stu(models.Model): name = models.CharField(max_length=32, verbose_name="name") gpa = models.IntegerField(verbose_name="gpa") @classmethod def get_all(cls): return cls.objects.all()
url //
app_name = "view" urlpatterns = [ path('view/', ListStuView.as_view(), name="list"), path('detail/<name>/', SingleStu.as_view()), ]
视图集不用写路由,但是类视图要写。
serializer //
class StuSerializer(serializers.ModelSerializer): # 自定义一个用于序列化student模型的序列化类 class Meta: model = Stu fields = ( "name", "gpa", )
views //
class ListALLStudentsView(ListCreateAPIView): queryset = Stu.get_all() serializer_class = StuSerializer class SingleStu(RetrieveUpdateDestroyAPIView): queryset = Stu.get_all() serializer_class = StuSerializer lookup_url_kwarg = "name"