建立model数据库

  1. from django.db import models
  2. __all__ = ['Book', 'Publisher', 'Author']
  3. # Create your models here.
  4. class Book(models.Model):
  5. title = models.CharField(max_length=32)
  6. CHOICES = ((1, 'python'), (2, 'linux'), (3, 'go'))
  7. category = models.IntegerField(choices=CHOICES, default=1, verbose_name='分类')
  8. pub_time = models.DateField(verbose_name='出版日期')
  9. publisher = models.ForeignKey(to='Publisher', verbose_name='出版社')
  10. authors = models.ManyToManyField(to='Author', verbose_name='作者')
  11. class Meta:
  12. db_table = 'book'
  13. verbose_name = '书籍表'
  14. verbose_name_plural = verbose_name
  15. def __str__(self):
  16. return self.title
  17. class Publisher(models.Model):
  18. name = models.CharField(max_length=32, verbose_name='出版社')
  19. address = models.CharField(max_length=32, verbose_name='地址')
  20. class Meta:
  21. db_table = 'publisher'
  22. verbose_name = '出版社表表'
  23. verbose_name_plural = verbose_name
  24. def __str__(self):
  25. return self.name
  26. class Author(models.Model):
  27. name = models.CharField(max_length=32, verbose_name='作者')
  28. country = models.CharField(max_length=32, verbose_name='国家')
  29. class Meta:
  30. db_table = 'author'
  31. verbose_name = '作者表'
  32. verbose_name_plural = verbose_name
  33. def __str__(self):
  34. return self.name

数据库部分一共三张表,书籍表以及作则和出版社表

admin注册

  1. from django.contrib import admin
  2. from SerDemo import models
  3. # Register your models here.
  4. for table in models.__all__:
  5. admin.site.register(getattr(models,table))

这里用到了小技巧,利用导入的models.__all__循环批量注册model模型

序列器的实现

在项目下新建serializers,py文件

  1. from rest_framework import serializers
  2. from SerDemo.models import Book, Author, Publisher
  3. # 自定义检验函数在字段参数validators中作为参数添加
  4. def my_validate(value):
  5. if "敏感词汇" in value.lower():
  6. raise serializers.ValidationError("输入的信息含有敏感词汇")
  7. return value
  8. ### 创建django序列化器类,继承serializers.ModelSerializer字段可自动关联
  9. class BookSerializer(serializers.ModelSerializer):
  10. ## 需要重写的字段,SerializerMethodField 会去找get_字段名的函数并执行获取返回值作为字段值
  11. category_read = serializers.SerializerMethodField(read_only=True,validators=[my_validate,])
  12. publisher_read = serializers.SerializerMethodField(read_only=True)
  13. authors_read = serializers.SerializerMethodField(read_only=True)
  14. # category_read的钩子函数,返回要显示的值,注意obj是每个要显示到前端的数据对象
  15. def get_category_read(self,obj):
  16. return obj.get_category_display()
  17. # publisher_read的钩子函数,返回要显示的值
  18. def get_publisher_read(self,obj):
  19. return {'id':obj.publisher_id,'title':obj.publisher.name}
  20. def get_authors_read(self,obj):
  21. ret = [{'id':i.id,'name':i.name} for i in obj.authors.all()]
  22. return ret
  23. ## 全局校验钩子函数
  24. def validate(self, attrs):
  25. # attrs 包含所有字段的数据
  26. if 'se' in attrs['title']:
  27. #如果敏感词汇在title字段中则抛出错误
  28. raise serializers.ValidationError('含有敏感词汇')
  29. # 否则返回原信息
  30. return attrs
  31. # 局部校验钩子函数validate_+字段名
  32. def validate_title(self, data):
  33. if 'se' in data:
  34. raise serializers.ValidationError('含有敏感词汇')
  35. return data
  36. # 序列化器的元信息
  37. class Meta:
  38. # 绑定的数据表model
  39. model=Book
  40. #要展示的表的字段
  41. fields = '__all__'
  42. # depth = 1
  43. # depth 让你所有的外键关系变成read_only=True,不建议使用
  44. # 额外要添加的字段的属性参数
  45. extra_kwargs = {
  46. 'category':{'write_only':True},
  47. 'publisher': {'write_only': True},
  48. 'authors':{'write_only':True},
  49. }

路由以及视图函数部分

  1. from django.conf.urls import url
  2. from SerDemo.views import BooklistView,EditBookView
  3. urlpatterns = [
  4. # 展示书籍信息路由
  5. url(r'^booklist/',BooklistView.as_view()),
  6. #编辑书籍路由,接受id参数
  7. url(r'^editbook/(?P<id>\d+)/',EditBookView.as_view())
  8. ]

视图部分

展示所有书籍数据和添加数据视图,

  1. class BooklistView(ListCreateModelMixin):
  2. #get 请求发送所有数据给前端
  3. def get(self, request):
  4. # 获取数据库中所有数据对象
  5. query_set = Book.objects.all()
  6. # 将queryset对象传给序列化器实例化,many=True告诉序列化器这是多个对象
  7. ser_obj = BookSerializer(query_set, many=True)
  8. # 所有要显示的数据都在ser_obj.data中用restframe的Response返回
  9. return Response(ser_obj.data)
  10. # post请求为添加数据
  11. def post(self, request):
  12. # 序列化前端传过来的数据(request.data)
  13. ser_obj = BookSerializer(data=request.data)
  14. # 校验各字段数据是否符合要求
  15. if ser_obj.is_valid():
  16. ser_obj.save()
  17. return Response(ser_obj.data)
  18. else:
  19. return Response(ser_obj.errors)

编辑数据和删除书籍部分

  1. class EditBookView(UpdateDestroyModelMixin):
  2. # 展示当前要编辑的数据对象
  3. def get(self, request, id):
  4. #根据url中的id参数获取要编辑数据对象
  5. book_obj = Book.objects.filter(id=id).first()
  6. if book_obj:
  7. # 返回给前端页面
  8. ser_obj = BookSerializer(book_obj)
  9. return Response(ser_obj.data)
  10. return Response('没有')
  11. #put请求对应修改数据
  12. def put(self, request, id):
  13. #根据url中的id参数获取要编辑数据对象
  14. book_obj = Book.objects.filter(id=id).first()
  15. if book_obj:
  16. #将前端提交的数据和要修改的对象传给序列化器partial=True允许只修改部分字段数据
  17. ser_obj = BookSerializer(data=request.data, instance=book_obj, partial=True)
  18. if ser_obj.is_valid():
  19. ser_obj.save()
  20. return Response(ser_obj.data)
  21. else:
  22. return Response(ser_obj.errors)
  23. def delete(self,request,id):
  24. book_obj = Book.objects.filter(id=id).first()
  25. if book_obj:
  26. book_obj.delete()
  27. return Response('')
  28. return Response('没有次对象')

模仿djngo restframe源码封装各个方法

  1. from django.shortcuts import render, HttpResponse, redirect
  2. from django.http import JsonResponse
  3. import json
  4. from SerDemo.models import Author, Publisher, Book
  5. from django import views
  6. from rest_framework import serializers
  7. from rest_framework.views import APIView
  8. from rest_framework.response import Response
  9. from SerDemo.serializers import BookSerializer
  10. # 把每个方法抽离出来
  11. class GenericAPIView(APIView):
  12. query_set = None
  13. serializer_class = None
  14. def _get_queryset(self):
  15. return self.query_set
  16. def _get_serializer(self,*args,**kwargs):
  17. return self.serializer_class(*args,**kwargs)
  18. class ListModelMixin:
  19. def list(self):
  20. query_set = self._get_queryset().all()
  21. ser_obj = self._get_serializer(query_set, many=True)
  22. return Response(ser_obj.data)
  23. class CreateModelMixin:
  24. def create(self,request):
  25. ser_obj = self._get_serializer(data=request.data)
  26. if ser_obj.is_valid():
  27. ser_obj.save()
  28. return Response(ser_obj.data)
  29. else:
  30. return Response(ser_obj.errors)
  31. class RetrieveModelMixin:
  32. def retrieve(self,id):
  33. book_obj = self._get_queryset().filter(id=id).first()
  34. if book_obj:
  35. ser_obj = self._get_serializer(book_obj)
  36. return Response(ser_obj.data)
  37. return Response('没有')
  38. class UpdateModelMixin:
  39. def update(self,request,id):
  40. book_obj = self._get_queryset().filter(id=id).first()
  41. if book_obj:
  42. ser_obj = self._get_serializer(data=request.data, instance=book_obj, partial=True)
  43. if ser_obj.is_valid():
  44. ser_obj.save()
  45. return Response(ser_obj.data)
  46. else:
  47. return Response(ser_obj.errors)
  48. class DestroyModelMixin:
  49. def destroy(self,id):
  50. book_obj = self._get_queryset().filter(id=id).first()
  51. if book_obj:
  52. book_obj.delete()
  53. return Response('')
  54. return Response('没有次对象')
  55. class ListCreateModelMixin(GenericAPIView,ListModelMixin, CreateModelMixin):
  56. pass
  57. class UpdateDestroyModelMixin(GenericAPIView,DestroyModelMixin,UpdateModelMixin,RetrieveModelMixin):
  58. pass
  59. class BooklistView(ListCreateModelMixin):
  60. query_set = Book.objects.all()
  61. serializer_class = BookSerializer
  62. def get(self, request):
  63. # query_set = Book.objects.all()
  64. # ser_obj = BookSerializer(query_set, many=True)
  65. # return Response(ser_obj.data)
  66. return self.list()
  67. def post(self, request):
  68. # ser_obj = BookSerializer(data=request.data)
  69. # if ser_obj.is_valid():
  70. # ser_obj.save()
  71. # return Response(ser_obj.data)
  72. # else:
  73. # return Response(ser_obj.errors)
  74. return self.create(request)
  75. class EditBookView(UpdateDestroyModelMixin):
  76. query_set = Book.objects.all()
  77. serializer_class = BookSerializer
  78. def get(self, request, id):
  79. # book_obj = Book.objects.filter(id=id).first()
  80. # if book_obj:
  81. # ser_obj = BookSerializer(book_obj)
  82. # return Response(ser_obj.data)
  83. # return Response('没有')
  84. return self.retrieve(id)
  85. def put(self, request, id):
  86. # book_obj = Book.objects.filter(id=id).first()
  87. # if book_obj:
  88. # ser_obj = BookSerializer(data=request.data, instance=book_obj, partial=True)
  89. # if ser_obj.is_valid():
  90. # ser_obj.save()
  91. # return Response(ser_obj.data)
  92. # else:
  93. # return Response(ser_obj.errors)
  94. return self.update(request,id)
  95. def delete(self,request,id):
  96. # book_obj = Book.objects.filter(id=id).first()
  97. # if book_obj:
  98. # book_obj.delete()
  99. # return Response('')
  100. # return Response('没有次对象')
  101. return self.destroy(id)

Django restframe 视图函数以及ModelSerializer的使用的更多相关文章

  1. Django之视图函数总结

    Django之视图函数总结 HttpRequest与HttpResponse http请求中产生两个核心对象: HttpRequest对象:用户请求相关的所有信息(对象) HttpResponse对象 ...

  2. django views视图函数返回值 return redirect httpresponse总结

    django views视图函数返回值 return redirect  render httpresponse总结

  3. Django 定义视图函数

    Django 定义视图函数 一.接收内容及文件处理 1.接收分类 # 获取数据 request.GET # 提交数据 request.POST # 获取文件 request.FILES 2.check ...

  4. 03 Django之视图函数

    一.Django的视图函数view 一个视图函数(类),简称视图,是一个简单的Python函数(类),它接受WEB请求并返回Web响应. 响应可以是一张网页的HTML内容,一个重定向,一个404错误, ...

  5. django的视图函数

    一.视图函数view 视图函数是接收一个请求(request对象),并返回响应的函数 1. HttpResponse响应请求 这个方法是返回字符串一类的,可以识别标签 2. render响应请求 re ...

  6. Django的视图函数和路由系统中一些没有用过的小点

    1.request对象 print("返回用户访问的url,但是不包括域名",request.path_info) print("返回请求的方法,全大写",re ...

  7. django views视图函数

    Django views.py视图文件 一. 创建views.py文件,在工程文件夹根目录创建views.py视图文件,其实任意文件名都可以,使用views是为了遵循传统. 注:所有的views函数都 ...

  8. Django中非视图函数获取用户对象

    今天遇到了一个问题:在Django中怎么从非视图函数中获取用户对象?怎么保证不同的请求获取到不同的用户对象? 平常我们获取用户对象使用的是: request.user 不得不说,这确实很方便. 但是, ...

  9. django中视图函数的FBV和CBV

    1.什么是FBV和CBV FBV是指视图函数以普通函数的形式:CBV是指视图函数以类的方式. 2.普通FBV形式 def index(request): return HttpResponse('in ...

随机推荐

  1. django 接受 ajax 传来的数组对象

    django 接受 ajax 传来的数组对象 发送:ajax 通过 POST 方式传来一个数组 接收:django 接受方式 array = request.POST.getlist(‘key[]’) ...

  2. Autofac踩坑经历

    背景 接口框架使用反射,动态生成Controller,使用Autofac进行依赖注入,并替换默认DependencyResolver及IControllerFactory,Controller实例化代 ...

  3. Centos7修改系统时区

    timedatectl status Local time: 四 2014-12-25 10:52:10 CST Universal time: 四 2014-12-25 02:52:10 UTC R ...

  4. Array Division CodeForces - 808D (构造+实现)

    Vasya has an array a consisting of positive integer numbers. Vasya wants to divide this array into t ...

  5. 提取PPT文件中的Vba ProjectStg Compressed Atom。Extract PPT VBA Compress Stream

    http://msdn.microsoft.com/en-us/library/cc313106(v=office.12).aspx  微软文档 PartI ********************* ...

  6. ios 后台下载,断点续传总结

    2018年12月05日 16:09:00 weixin_34101784 阅读数:5 https://blog.csdn.net/weixin_34101784/article/details/875 ...

  7. Volterra方程的不动点

  8. 47.Majority Element I & II

    Majority Element I 描述 给定一个整型数组,找出主元素,它在数组中的出现次数严格大于数组元素个数的二分之一. You may assume that the array is non ...

  9. js判断数组是否包含某个字符串变量的实例

    最近碰到一个这样的现象,后台返回的数据中,数组里面有一些有变量值,有一些没有变量值. 举个例子,比如后台返回的例子是这样的: var arr=[ { "status":" ...

  10. spring AOP源码分析(三)

    在上一篇文章 spring AOP源码分析(二)中,我们已经知道如何生成一个代理对象了,那么当代理对象调用代理方法时,增强行为也就是拦截器是如何发挥作用的呢?接下来我们将介绍JDK动态代理和cglib ...