使用restframework
https://www.cnblogs.com/GGGG-XXXX/articles/9568816.html
第一步: 安装
pip install djangorestframework pip install markdown # Markdown 支持可浏览的API pip install django-filter # 支持过滤
第二步: 注册rest_framework 在settings中的INSTALLEED_APPS
INSTALL_APPS = ( ......, 'rest_framework' )
第三步: 创建表,(models.py)

from django.db import models # Create your models here. __all__ = ["Book", "Publisher", "Author"] CHOICES = ((1, "Python"), (2, "linux"), (3, "Go")) class Book(models.Model): title = models.CharField(max_length=32, verbose_name="图书名字") category = models.IntegerField(choices=CHOICES) pub_time = models.DateField() publisher = models.ForeignKey(to="Publisher") authors = models.ManyToManyField(to="Author") def __str__(self): return self.title class Meta: db_table = "01-图书表" verbose_name_plural = db_table class Publisher(models.Model): title = models.CharField(max_length=32) def __str__(self): return self.title class Meta: db_table = "02-出版社" verbose_name_plural = db_table class Author(models.Model): name = models.CharField(max_length=32, verbose_name="作者的名字") def __str__(self): return self.name class Meta: db_table = "03-作者表" verbose_name_plural = db_table

from django.contrib import admin from . import models for table in models.__all__: admin.site.register(getattr(models, table))
第四步: 创建序列化器, 在APP中创建serializers.py文件

from rest_framework import serializers from .models import Book # 理解该文件的内容,为需要传输转换为json的字段的内容 class PublisherSerializer(serializers.Serializer): id = serializers.IntegerField() title = serializers.CharField(max_length=32) class AuthorSerializer(serializers.Serializer): id = serializers.IntegerField() name = serializers.CharField(max_length=32) class BookSerializer(serializers.Serializer): id = serializers.IntegerField(required=False) title = serializers.CharField(max_length=32) CHOICES = ((1, "Python"), (2, "Linux"), (3, "Go")) category = serializers.CharField(max_length=32, source="get_category_display", read_only=True) post_category = serializers.ChoiceField(choices=CHOICES, write_only=True) pub_time = serializers.DateField() publisher = PublisherSerializer(read_only=True) authors = AuthorSerializer(many=True, read_only=True) publisher_id = serializers.IntegerField(write_only=True) author_list = serializers.ListField(write_only=True) def create(self, validated_data): # 创建验证通过的字段 book_obj = Book.objects.create(title=validated_data["title"], category=validated_data["post_category"], pub_time=validated_data["pub_time"], publisher_id=validated_data["publisher_id"]) # 多对多关系的用add添加 book_obj.authors.add(*validated_data["author_list"]) return book_obj def update(self, instance, validated_data): # 有就更新, 没有就是默认的. instance.title = validated_data.get("title", instance.title) instance.category = validated_data.get("post_category", instance.category) instance.pub_time = validated_data.get("pub_time", instance.pub_time) instance.publisher_id = validated_data.get("publisher_id", instance.publisher_id) # 多对多关系字段的更新 if validated_data.get("author_list"): instance.authors.set(*validated_data["author_list"]) # 注意要保存 instance.save() return instance
第五步: 视图函数

from rest_framework.views import APIView from rest_framework.response import Response from .models import Book from .serializers import BookSerializer # Create your views here. class BookInfo(APIView): def get(self, request): book_list = Book.objects.all() ser_obj = BookSerializer(book_list, many=True) return Response(ser_obj.data) def post(self, request): book_obj = request.data print(request.data) ser_obj = BookSerializer(data=book_obj) if ser_obj.is_valid(): print(ser_obj.validated_data) ser_obj.save() return Response(ser_obj.validated_data) else: return Response(ser_obj.errors) # 筛选某个字段 class BookEditView(APIView): def get(self, request, id): book_obj = Book.objects.filter(id=id).first() ser_obj = BookSerializer(book_obj) return Response(ser_obj.data) def patch(self, request, id): book_obj = Book.objects.filter(id=id).filter() ser_obj = BookSerializer(instance=book_obj, data=request.data, partial=True) if ser_obj.is_valid(): ser_obj.is_valid() return Response(ser_obj.validated_data) else: return Response(ser_obj.errors)
第六步: 设计url

from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^booklist/$', views.BookInfo.as_view()), url(r'^booklist/id=(?P<id>\d+)', views.BookEditView.as_view()) ]
restframework阶段总结
安装:
pip install djangorestframework
settings 中注册rest_framework APP
序列化
声明一个序列化器
类比models
视图
class BookView(APIView): def get(self, request): queryset = Book.objectsd.all() ser_obj = BookSerializer(quesyset, many=True)
反序列化
声明序列化器
注意我们的正序跟反序列化字段类型不统一
read_only
write_only
require=False
自定义create
自定义update
视图
class BookView(APIView): def post(self, request): ser_obj = BookSerializer(data=request.data) if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj.validated_data) else: return Response(ser_obj.errors)
class BookEditView(APIView): def put(self, request, id): book_obj = Book.objects.filter(id=id).first() ser_obj = BookSerializer(book_obj, data=request.data, partial=True) if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj, validated_data) else: return Response(ser_obj.errors)
注意这两个的区别.
验证
单个字段的验证
def validate_字段名称(self, value): # 处理我们的验证逻辑
多个字段的验证
def validate(self, attrs): attrs 所有传过来的数据 {} 字典里含有字段的名称: 值
自定义验证
def my_validate(value): 处理自己的验证逻辑 给我们的字段加属性 validators=[my_validate]
验证通过返回传进来的值
验证不通过 raise serialisers.ValidationError("错误信息")
ModelSerializer
序列化
class BookSerializer(serializers.ModelSerialezer): class Meta: model = Book field = "__all__" # 让我们的外键关系字段编程read_only=True depth = 1
反序列化
class BookSerializer(serializers.Moddelzer): class Meta: model = Book field = ["id", "name"]
SerializerMethodField
publisher_info = serializers.SerializseMethodField()
def get_字段名称(self, obj):
obj序列化的每个模型对象
通过ORM操作拿到自己想要的数据结构
return 想要的数据结构
增加额外的参数
extra_kwargs = {"category": {"write_only": True},"publisher": {"write_only": True}, "authors":{"write_only": True},"title": {"validators": [my_validate]}}
视图
APIView View区别
APIView继承View
重新封装了request对象, 用Request类封装
旧的request _request
request.data 所有的数据
request.quesry_params GET
封装的流程
每个视图都要配置queryset serializer_class
querset = Book.objects.all()
serializer_class = BookSerializer()
class GenericAPIView(APIView):
def get_queryset(self):
return self.queryset.all()
def get_serializer(self, *args, **kwargs):
return self.get_serialize(*args, **kwargs)
写每个方法类
class ListModeMixin(object):
def list(self, request):
原来的get方法逻辑
获取queryset self.get_queryset
获取序列化器 self.get-serializers(...)
-- 修改视图
class BookAPIView(GenericAPIView, ListModelMixin):
querset = Book.objects.all()
serializer_class = BookSerializer
def get(self, request):
return self.list(request)
-- 路由的传参
-- 希望按照我们的指定的去分发
-- ViewSetMixin 重写as_view() 可以传参了
-- 合并视图 ModelViewSet
对之前的代码进行封装(views.py)
第一步: 导入ViewSetMixin和ModelViewSet模块
from rest_framework.viewsets import ViewSetMixin, ModelVsiewSet
1,初步抽出
2, 抽离出获取的操作
3, 最终结果

from rest_framework.views import APIView from rest_framework.response import Response from .models import Student from .serializers import StudentInfoSerializer from rest_framework.viewsets import ViewSetMixin, ModelViewSet class GenericAPIView(APIView): # 每个表通过继承这个类,实现获取不同的queryset对象, 和serializer_class queryset = None serializer_class = None def get_queryset(self): return self.queryset.all() def get_serializer(self, *args, **kwargs): return self.serializer_class(*args, **kwargs) class ListModelMixin(object): # get 方法 def list(self, request): queryset = self.get_queryset() ser_obj = self.get_serializer(queryset, many=True) return Response(ser_obj.data) class ListCreateModelMixin(GenericAPIView, ListModelMixin): pass class StudentInfo(ListCreateModelMixin): # 获取该表的queryset对象, 和序列化对象 queryset = Student.objects.all() serializer_class = StudentInfoSerializer def get(self, request): return self.list(request)
其余的都一样

from rest_framework.views import APIView from rest_framework.response import Response from .models import Student from .serializers import StudentInfoSerializer from rest_framework.viewsets import ViewSetMixin, ModelViewSet class GenericAPIView(APIView): # 每个表通过继承这个类,实现获取不同的queryset对象, 和serializer_class queryset = None serializer_class = None def get_queryset(self): return self.queryset.all() def get_serializer(self, *args, **kwargs): return self.serializer_class(*args, **kwargs) class ListModelMixin(object): # get 方法 def list(self, request): queryset = self.get_queryset() ser_obj = self.get_serializer(queryset, many=True) return Response(ser_obj.data) class CreateModelMixin(object): # post 方法 def create(self, request): queryset = request.data ser_obj = self.get_serializer(data=queryset) if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj.validated_data) else: return Response(ser_obj.errors) class RetrieveModelMixin(object): def retrieve(self, request, id): obj = self.get_queryset().filter(id=id).first() ser_obj = self.get_serializer(obj) return Response(ser_obj.data) class UpdateModelMixin(object): def update(self, request, id): obj = self.get_queryset().filter(id=id).first() ser_obj = self.get_serializer(instance=obj, data=request.data, partial=True) if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj.validated_data) else: return Response(ser_obj.errors) class ListCreateModelMixin(GenericAPIView, ListModelMixin, CreateModelMixin): pass class RetrieveUpdateDestroyModelMixin(GenericAPIView, RetrieveModelMixin, UpdateModelMixin): pass class StudentInfo(ListCreateModelMixin): # 获取该表的queryset对象, 和序列化对象 queryset = Student.objects.all() serializer_class = StudentInfoSerializer def get(self, request): return self.list(request) def post(self, request): return self.create(request) # def get(self, request): # studentInfo = Student.objects.all() # ser_stu = StudentInfoSerializer(studentInfo, many=True) # return Response(ser_stu.data) # def post(self, request): # studentInfo = request.data # ser_obj = StudentInfoSerializer(data=studentInfo) # if ser_obj.is_valid(): # ser_obj.save() # return Response(ser_obj.validated_data) # else: # return Response(ser_obj.errors) class StudentUpdate(RetrieveUpdateDestroyModelMixin): queryset = Student.objects.all() serializer_class = StudentInfoSerializer def get(self, request, id): return self.retrieve(request, id) # def get(self, request, id): # studentInfo = Student.objects.filter(id=id).first() # ser_stu = StudentInfoSerializer(studentInfo) # return Response(ser_stu.data) def patch(self, request, id): return self.update(request, id) # def patch(self, request, id): # studentInfo = Student.objects.filter(id=id).first() # ser_stu = StudentInfoSerializer(instance=studentInfo, data=request.data, partial=True) # if ser_stu.is_valid(): # ser_stu.save() # return Response(ser_stu.validated_data) # else: # return Response(ser_stu.errors)
使用restframework封装好的实现
url.py
from django.conf.urls import url from django.contrib import admin from app01 import my_view urlpatterns = [ url(r'^admin/', admin.site.urls), # url(r'^api-schoolinfo/$', my_view.StudentInfo.as_view()), # url(r'^api-schoolinfo/(?P<id>\d+)$', my_view.StudentUpdate.as_view()), url(r'^api-schoolinfo/$', my_view.StudentsInfoAPIView.as_view({"get": "list", "post": "create"})), url(r'^api-schoolinfo/(?P<pk>\d+)$$', my_view.StudentsInfoAPIView.as_view({"get": "retrieve", "patch": "update", "delete": "destroy"})), ]
serializers.py
class StudentsInfoAPIView(ModelViewSet): queryset = Student.objects.all() serializer_class = StudentInfoSerializer
分析url设置对应的源码分析
ModelViewSet ---> GenericViewSet ---> ViewSetMixin
使用serializers.ModelSerializer

class BookSerializer(serializers.ModelSerializer): category_dis= serializers.SerializerMethodField(read_only=True) publisher_info = serializers.SerializerMethodField(read_only=True) author_info = serializers.SerializerMethodField(read_only=True) def get_author_info(self, obj): # 通过obj拿到authors # 构建想要的数据结构返回 authors = obj.authors.all() ret = [] for author in authors: ret.append({ "id": author.id, "name": author.name }) return ret def get_category_dis(self, obj): return obj.get_category_display() def get_publisher_info(self, obj): # 序列化的Book对象 # 通过Book对象找到我们的publisher对象 # 就可以拿到我们想要的字段 # 拼接成自己想要的数据结构 ret = { "id": obj.publisher.id, "title": obj.publisher.title } return ret class Meta: model = Book # fields = ["id", "title", "put_time"] fields = "__all__" # 让你这些外键关系的字段变成read_only = True # depth = 1 extra_kwargs = {"category": {"write_only": True},"publisher": {"write_only": True}, "authors":{"write_only": True},"title": {"validators": [my_validate]}}
https://www.cnblogs.com/GGGG-XXXX/articles/9675911.html