博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django REST framework序列化
阅读量:4340 次
发布时间:2019-06-07

本文共 6943 字,大约阅读时间需要 23 分钟。

一.简介

Django REST framework是基于Django实现的一个RESTful风格API框架,能够帮助我们快速开发RESTful风格的API。

官网:

中文文档:

二. 安装与配置

1.安装

pip install djangorestframework

2.配置

如果想要获取一个图形化的页面,需要将 rest_framework 注册到项目的INSTALL_APPS中。

INSTALLED_APPS = [    'django.contrib.admin',    'django.contrib.auth',    'django.contrib.contenttypes',    'django.contrib.sessions',    'django.contrib.messages',    'django.contrib.staticfiles',    'bms.apps.BmsConfig',    'rest_framework',]

三.DRF序列化

我们写项目想返回的是json数据,使用DRF的序列化工具serializer会非常方便

url:

re_path('books/$',views.BooksView.as_view()),    re_path(r'book_pk/(?P
\d+)$', views.BookDetailView.as_view()),

view:

from rest_framework.views import APIViewfrom app01.serializers import BookModelSerializerclass BooksView(APIView):    # 不带id的查询与新增    """使用Django REST framework 内置的序列化"""    def get(self, request):        '''以JSON格式返回所有的书籍信息'''        # 1.查出所有的书籍信息        queryset = models.Book.objects.all()        # 2.使用serializers序列化        ser_obj = BookModelSerializer(queryset, many=True) # 多条数据many=True        return Response(ser_obj.data)    def post(self, request):        '''创建资源'''        # 1.获取前端提交的数据        # 1.1 APIView        # self.request是谁?  不是Django原来的哪个request  self._request才是原来的request        # print(request.data)  # APIView 包装的数据        # 2.对数据做有效性校验        ser_obj = BookModelSerializer(data=request.data)        if ser_obj.is_valid():            ser_obj.save() # 调用的是BookSerializer类中的create方法,需要自己去实现            # 3. 拿到序列化的数据去数据库创建新记录            return Response("ok")        else:            return Response(ser_obj.errors)class BookDetailView(APIView):    '''查询具体的书籍,编辑书籍,删除书籍'''    def get(self, request, pk):        # 1,根据pk去查询具体的哪儿本书籍对象        book_obj = models.Book.objects.filter(pk=pk).first()        if book_obj:            # 2. 将书籍对象 序列化成 json格式的数据            ser_obj = BookModelSerializer(book_obj)            # 3. 返回响应            return Response(ser_obj.data)        else:            return Response("无效的书籍id")    def put(self, request, pk):        """修改具体某一本书"""        # 1. 根据pk去查询具体的那本书籍对象        book_obj = models.Book.objects.filter(pk=pk).first()        if book_obj:            # 2. 获取用户 发送过来的数据并且更新对象            # partial=True 允许局部更新,比如只改变部分数据(partial 局部的)            ser_obj = BookModelSerializer(instance=book_obj, data=request.data, partial=True)  # form组件中也有类似的实现            if ser_obj.is_valid():                # 3. 保存并返回修改后的数据                ser_obj.save()                return Response(ser_obj.data)            else:                return Response(ser_obj.errors)        else:            return Response("无效的书籍id")    def delete(self, request, pk):        '''删除具体某一本书'''        # 1. 根据pk去查询具体的那本书籍queryset对象;注意不是具体的书籍对象,书籍对象没有delete方法        book_obj = models.Book.objects.filter(pk=pk)        if book_obj:            # 删除书籍对象            book_obj.delete()            return Response("删除成功")        else:            return Response("无效的书籍id")
serializers.py
class BookSerializers(serializers.Serializer):    '''使用Serializer,序列化'''    id = serializers.IntegerField(required=False) # required=False 设置为非必须要字段    title = serializers.CharField(max_length=32)    pub_date = serializers.DateField()    CHOICES = ((1, 'Python'), (2, 'Go'), (3, 'Linux'))    # read_only=True 设置为只在查询字段时生效    category = serializers.CharField(source='get_category_display', read_only=True)    # read_only=True 设置为只在添加字段,或修改字段时生效    post_category = serializers.IntegerField(write_only=True)    publisher = PublisherSerializer(read_only=True)    post_publisher = serializers.IntegerField(write_only=True)    # many= True 当字段对应多条数据时使用    authors = AuthorSerializer(many=True, read_only=True)    post_authors = serializers.ListField(write_only=True)    def validate_title(self, attrs):        """类似于Form组件的局部勾子函数"""        # attrs就是需要检验的这个字段的值        print(attrs) # 红烧牛肉        print('-' * 120)        if '红烧牛肉' in attrs:            raise serializers.ValidationError('你是魔鬼吗?')        else:            return attrs    def validate_post_publisher(self, attrs):        # 判断数据库里面有没有你制定的这个出版社        is_exist = models.Publisher.objects.filter(pk=attrs)        if is_exist:            return attrs        else:            raise serializers.ValidationError("你填写的出版社不存在!")    # 全局钩子    # def validate(self, attrs):    #     pass    # 校验合格的数据,要想直接 .save()保存数据必须要重写这个方法    def create(self, validated_data):        # validated_data经过校验的有效数据        book_obj = models.Book.objects.create(            title=validated_data['title'],            pub_date=validated_data['pub_date'],            category=validated_data['post_category'],            publisher_id=validated_data['post_publisher'],  # 1        )        book_obj.authors.set(validated_data['post_authors'])        return book_obj    # 在更新数据的时候支持直接调用save()保存数据    def update(self, instance, validated_data):        # print(instance) # 查询出要改变的原数据        # print(validated_data) # 校验合格的更新数据        # 从validated_data中取出数据挨个字段更新        instance.title = validated_data.get('title', instance.title)        instance.pub_date = validated_data.get('pub_date', instance.pub_date)        instance.category = validated_data.get('post_category', instance.category)        instance.publisher_id = validated_data.get('post_publisher', instance.publisher_id)        # 永远都不要高估自己!        instance.save()        # 更新多对多字段的 authors        # 先取出当前书籍的所有作者id        author_list = instance.authors.all().values_list('id')  # [(1,),(2,)] ==> [1, 2]        # 然后更新,没变就用原来的数据        instance.authors.set(validated_data.get('post_authors',[i[0] for i in author_list]))        # 返回更新后的数据        return instance# 使用modelserializersclass BookModelSerializer(serializers.ModelSerializer):    '''使用ModelSerializer,序列化'''    # SerializerMethodField 会自动去找 get_字段名 的方法执行(设置了SerializerMethodField)    category_info = serializers.SerializerMethodField(read_only=True) # 查到关联的对象    publisher_info = serializers.SerializerMethodField(read_only=True)    authors_info = serializers.SerializerMethodField(read_only=True)    def get_category_info(self, book_obj):        # book_obj ==》 当前被序列化的那个书籍对象        return book_obj.get_category_display()    def get_publisher_info(self, book_obj):        # book_obj.pulisher  ==> 得到和我这本书关联的出版社对象        # return {
# "id": book_obj.publiser.id, # "name": book_obj.publiser.name # } # ser_obj = PublisherSerializer(book_obj.publisher) # return ser_obj.data return PublisherSerializer(book_obj.publisher).data def get_authors_info(self, book_obj): return AuthorSerializer(book_obj.authors.all(), many=True).data class Meta: model = models.Book fields = "__all__" # depth 1 # 所有有关系的字段都变成 read_only # exclude = [] # 排除某个字段 extra_kwargs = { # 每个字段的一些额外参数也可更改 'publisher': {
'write_only': True}, 'authors': {
'write_only': True}, 'category': {
'write_only': True}, }

 

转载于:https://www.cnblogs.com/zwq-/p/10263888.html

你可能感兴趣的文章
eclipse没有server选项
查看>>
CRC码计算及校验原理的最通俗诠释
查看>>
使用Gitbook来编写你的Api文档
查看>>
jquery扩展 $.fn
查看>>
Markdown指南
查看>>
influxDB的安装和简单使用
查看>>
JPA框架学习
查看>>
JPA、JTA、XA相关索引
查看>>
机器分配
查看>>
php opcode缓存
查看>>
springcloud之Feign、ribbon设置超时时间和重试机制的总结
查看>>
观看杨老师(杨旭)Asp.Net Core MVC入门教程记录
查看>>
UIDynamic(物理仿真)
查看>>
Windows下安装Redis
查看>>
winform非常实用的程序退出方法!!!!!(转自博客园)
查看>>
centos安装vim
查看>>
linux工作调度(计划任务)
查看>>
新部署到服务器 报 The requested URL /home/profession was not found on this server. 错误
查看>>
hadoop从非HA转到NAMENODE HA时需要注意的一个问题
查看>>
KnockoutJs学习笔记(十一)
查看>>