一、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 //
python
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 //
python
from django.contrib import admin
from rest_app.models import Students
admin.site.register(
Students
)
python
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 //
python
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 //
python
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 //
python
@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
python
@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"