DRF教程1-序列化
Serializers
Serializers 可以将queryset 和 model instance 转为为navite python datetype,然后render为JSON,给到api。也可以反序列化,把数据解析,验证数据,然后给到db。
django中的Serializer
class,可以控制响应的输出方式。
序列化类
要建立web API,要做的第一件事就是对实例进行序列化,比如以json方式显示。我们可以生命序列化,它和django的forms很相似。在app目录下创建serializers.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | from rest_framework import serializers from .models import Course class CourseSerializer(serializers.Serializer): """ Course序列化 """ id = serializers.IntegerField(read_only = True ) name = serializers.CharField(required = True ,max_length = 64 ) desc = serializers.CharField(required = True ,max_length = 512 ) detail = serializers.CharField(required = True ) learn_times = serializers.IntegerField(required = True ) degree = serializers.ChoiceField(choices = (( 'hard' , '较难' ),( 'middle' , '中级' ),( 'easy' , '简单' )), required = True ) students = serializers.IntegerField(required = True ) fav_num = serializers.IntegerField(required = True ) click_num = serializers.IntegerField(required = True ) catalog = serializers.CharField(required = True ,max_length = 32 ) # image = serializers.ImageField(required=True,max_length=64) # add_time = serializers.DateTimeField(required=True) def create( self , validated_data): """ Create and return a new `Course` instance, given the validated data. """ return Course.objects.create( * * validated_data) def update( self , instance, validated_data): """ Update and return an existing `Course` instance, given the validated data. """ instance.name = validated_data.get( 'name' , instance.name) instance.desc = validated_data.get( 'desc' , instance.desc) instance.detail = validated_data.get( 'detail' , instance.detail) instance.learn_times = validated_data.get( 'learn_times' , instance.learn_times) instance.degree = validated_data.get( 'degree' , instance.degree) instance.students = validated_data.get( 'students' , instance.students) instance.fav_num = validated_data.get( 'fav_num' , instance.fav_num) instance.click_num = validated_data.get( 'click_num' , instance.click_num) instance.catalog = validated_data.get( 'catalog' , instance.catalog) instance.save() return instance #序列化类的第一部分,定义了序列化/反序列化的字段。creata和update方法定义了调用serializer.save()时如何创建或者修改实例 # |
使用序列化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | from courses.models import Course from courses.serializer import CourseSerializer from rest_framework.renderers import JSONRenderer from rest_framework.parsers import JSONParser course = Course(name = "win桌面运维2" ,desc = "win桌面运维2" , detail = "jabbok授课" , learn_times = 120 ,degree = "middle" , students = 1 ,fav_num = 0 ,click_num = 0 ,catalog = "运维" ) course.save() #使用Course类创建一个course实例,然后保存(调用序列化类中的create方法) #这时这个字段已经在数据库中被创建,id字段自动出现 serializer = CourseSerializer(course) serializer.data { 'id' : 4 , 'name' : 'win桌面运维2' , 'desc' : 'win桌面运维2' , 'detail' : 'jabbok授课' , 'learn_times' : 120 , 'degree' : 'middle' , 'students' : 1 , 'fav_num' : 0 , 'click_num' : 0 , 'catalog' : '运维' } #使用自定义的CourseSerializer序列化类,对course实例创建序列化实例serializer #data属性显示序列化实例的数据 content = JSONRenderer().render(serializer.data) content b '{"id":4,"name":"win\xe6\xa1\x8c\xe9\x9d\xa2\xe8\xbf\x90\xe7\xbb\xb42","desc":"win\xe6\xa1\x8c\xe9\x9d\xa2\xe8\xbf\x90\xe7\xbb\xb42","detail":"jabbok\xe6\x8e\x88\xe8\xaf\xbe","learn_times":120,"degree":"middle","students":1,"fav_num":0,"click_num":0,"catalog":"\xe8\xbf\x90\xe7\xbb\xb4"}' #在这时的数据还是python数据格式,最后一步把数据render为json数据。 import io stream = io.BytesIO(content) data = JSONParser().parse(stream) serializer = CourseSerializer(data = data) serializer.is_valid() >>> True serializer.validated_data OrderedDict([( 'name' , 'win桌面运维2' ), ( 'desc' , 'win桌面运维2' ), ( 'detail' , 'jabbok授课' ), ( 'learn_times' , 120 ), ( 'degree' , 'middle' ), ( 'students' , 1 ), ( 'fav_num' , 0 ), ( 'click_num' , 0 ), ( 'catalog' , '运维' )]) serializer.save() <Course: win桌面运维 2 > #反序列化是相似的。先把一个steam解析为python数据格式 #然后把这个数据填充为一个实例对象。 serializer = CourseSerializer(Course.objects. all (), many = True ) serializer.data [OrderedDict([( 'id' , 1 ), ( 'name' , 'django入门' ), ( 'desc' , 'dj入门' ), ( 'detail' , 'jabbok的课程' ), ( 'learn_times' , 120 ), ( 'degree' , 'easy' ), ( 'students' , 12 ), ( 'fav_num' , 0 ), ( 'click_num' , 0 ), ( 'catalog' , '运维' )]), OrderedDict([( 'id' , 2 ), ( 'name' , '精通python' ), ( 'desc' , '精通python的课程' ), ( 'detail' , 'jabbok授课' ), ( 'learn_times' , 230 ), ( 'degree' , 'easy' ), ( 'students' , 12 ), ( 'fav_num' , 0 ), ( 'click_num' , 0 ), ( 'catalog' , '运维' )]), OrderedDict([( 'id' , 3 ), ( 'name' , 'win桌面运维' ), ( 'desc' , 'win桌面运维' ), ( 'detail' , 'jabbok授课' ), ( 'learn_times' , 120 ), ( 'degree' , 'middle' ), ( 'students' , 1 ), ( 'fav_num' , 0 ), ( 'click_num' , 0 ), ( 'catalog' , '运维' )]), OrderedDict([( 'id' , 4 ), ( 'name' , 'win桌面运维2' ), ( 'desc' , 'win桌面运维2' ), ( 'detail' , 'jabbok授课' ), ( 'learn_times' , 120 ), ( 'degree' , 'middle' ), ( 'students' , 1 ), ( 'fav_num' , 0 ), ( 'click_num' , 0 ), ( 'catalog' , '运维' )]), OrderedDict([( 'id' , 5 ), ( 'name' , 'win桌面运维2' ), ( 'desc' , 'win桌面运维2' ), ( 'detail' , 'jabbok授课' ), ( 'learn_times' , 120 ), ( 'degree' , 'middle' ), ( 'students' , 1 ), ( 'fav_num' , 0 ), ( 'click_num' , 0 ), ( 'catalog' , '运维' )])] #我们也可以把一个查询集序列化,加入many=True即可。 |
模型序列化
上面的序列化类和Course模型是高度相似的,django提供了ModelSerializer
类,可以对序列化类做简化,并且create和updata方法都默认在里面了。
1 2 3 4 | class CourseSerializer(serializers.ModelSerializer): class Meta: model = Course fields = ( 'id' , 'name' , 'desc' , 'detail' , 'learn_times' , 'degree' , 'students' , 'fav_num' , 'click_num' , 'catalog' ) |
1 2 3 4 5 | class CourseSerializer(serializers.ModelSerializer): class Meta: model = Course fields = '__all__' #如果序列化所以字段,就是要__all__ |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | from courses.serializer import CourseSerializer serializer = CourseSerializer() print ( repr (serializer)) CourseSerializer(): id = IntegerField(label = 'ID' , read_only = True ) name = CharField(label = '课程名称' , max_length = 64 ) desc = CharField(label = '课程描述' , max_length = 512 ) detail = CharField(label = '课程详情' , style = { 'base_template' : 'textarea.html' }) learn_times = IntegerField(label = '课程时长(分钟数)' , max_value = 2147483647 , min_value = - 2147483648 , required = False ) degree = ChoiceField(choices = (( 'hard' , '较难' ), ( 'middle' , '中级' ), ( 'easy' , '简单' )), label = '课程难度' ) students = IntegerField(label = '学习人数' , max_value = 2147483647 , min_value = - 2147483648 , required = False ) fav_num = IntegerField(label = '收藏人数' , max_value = 2147483647 , min_value = - 2147483648 , required = False ) click_num = IntegerField(label = '点击数' , max_value = 2147483647 , min_value = - 2147483648 , required = False ) catalog = CharField(label = '课程类别' , max_length = 32 ) #以上方法可以查看序列化类中包含的字段,可见,model中的字段都被继承过来了。 |
重写.create() update()
使用django常规view提供web API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | from django.http import HttpResponse, JsonResponse from django.views.decorators.csrf import csrf_exempt from rest_framework.renderers import JSONRenderer from rest_framework.parsers import JSONParser from .models import Course from .serializer import CourseSerializer @csrf_exempt def course_list(request): """ List all courses, or create a new course. """ if request.method = = 'GET' : courses = Course.objects. all () serializer = CourseSerializer(courses, many = True ) return JsonResponse(serializer.data, safe = False ) elif request.method = = 'POST' : data = JSONParser().parse(request) serializer = CourseSerializer(data = data) if serializer.is_valid(): serializer.save() return JsonResponse(serializer.data, status = 201 ) return JsonResponse(serializer.errors, status = 400 ) @csrf_exempt def course_detail(request, pk): """ Retrieve, update or delete a code course. """ try : course = Course.objects.get(pk = pk) except Course.DoesNotExist: return HttpResponse(status = 404 ) if request.method = = 'GET' : serializer = CourseSerializer(course) return JsonResponse(serializer.data) elif request.method = = 'PUT' : data = JSONParser().parse(request) serializer = CourseSerializer(course, data = data) if serializer.is_valid(): serializer.save() return JsonResponse(serializer.data) return JsonResponse(serializer.errors, status = 400 ) elif request.method = = 'DELETE' : course.delete() return HttpResponse(status = 204 ) |
1 2 3 4 5 6 | urlpatterns = [ path( 'admin/' , xadmin.site.urls), path( 'course/' , views.course_list,name = 'course_list' ), path( 'course/<int:pk>/' , views.course_detail,name = 'course_detail' ), ] #提供url |
1 2 3 4 5 6 7 | http http: / / 127.0 . 0.1 : 8008 / course / #列出所有courses,调用course_list视图 http http: / / 127.0 . 0.1 : 8008 / course / 1 / #传入pk参数,调用course_detail视图 #这里使用python下的httpie工具 |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步