一、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 modelsclass 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@classmethoddef get_all(cls):return cls.objects.all()
admin //
from django.contrib import adminfrom rest_app.models import Studentsadmin.site.register(Students
)
app下serializer.py //
from rest_framework import serializersfrom rest_app.models import Studentsclass StudentSerializer(serializers.ModelSerializer): # 自定义一个用于序列化student模型的序列化类class Meta:model = Studentsfields = ("id","name","age","gender","gpa",)
# 序列化:继承djangorestframework中的serialize。str(a dict), 是一个jason字符串。
views //
from rest_framework.decorators import api_view
from rest_framework.response import Responsefrom 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_namedef __str__(self):return self.class_name@classmethoddef get_all(cls):return cls.objects.all()
admin //
from django.contrib import adminfrom rest_app.models import Students, StudentsClamodels = [Students,StudentsCla ]admin.site.register(models)
serializer //
class StudentsClaSerializer(serializers.ModelSerializer): # 自定义一个用于序列化student模型的序列化类class Meta:model = StudentsClafields = ("class_name","mentor",)
views //
class ListStudentsClaViewSet(ModelViewSet):queryset = StudentsCla.get_all() # 使用模型视图集需要指定queryset的值和s_cserializer_class = StudentsClaSerializerpass
total urls //
from rest_framework import routersfrom rest_app.views import ListStudentsClaViewSetrouter = 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")@classmethoddef 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):passreturn 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):passreturn render(self.request, "", locals())def put(self, request):passdef 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 modelsclass Stu(models.Model):name = models.CharField(max_length=32, verbose_name="name")gpa = models.IntegerField(verbose_name="gpa")@classmethoddef 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 = Stufields = ("name","gpa",)
views //
class ListALLStudentsView(ListCreateAPIView):queryset = Stu.get_all()serializer_class = StuSerializerclass SingleStu(RetrieveUpdateDestroyAPIView):queryset = Stu.get_all()serializer_class = StuSerializerlookup_url_kwarg = "name"