django-rest-framework serializers.Serializer使用总结

django-rest-framework是构建web API的一个包,功能强大也很灵活,遵循restful标准,如果对于rest标准还不熟悉,推荐看一下阮一峰的文章

理解restful架构

restful设计指南

django-rest-framework安装

pip install djangorestframework
这篇文章对django-rest-framework有一个详细的综述,如果还不了解可以先看一下这篇文章。我在这里只对serializers.Serializer做一个概述。


1 创建django项目

    

django-admin startproject serializertutorial
django-admin startapp tutorial

然后在settings.py文件中添加rest_framework和创建的app

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

接下来配置settings.py文件中django链接数据库的参数,为了定义model。在此之前实现要创建好需要使用的数据库。

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django',
        'USER':'root',
        'PASSWORD':'root',
        'HOST':'127.0.0.1',
        'PORT':'3306'
    }
}

现在配置都做好了,就可以开始工程代码了。



2 创建model

    在创建好的app目录下编辑models.py,以创建一个文章model为例

from django.db import models

# Create your models here.
class Article(models.Model):
    author=models.CharField(max_length=20)
    title=models.CharField(max_length=30)
    content=models.TextField()
    created=models.DateTimeField(auto_now=True)

    class Meta:
        ordering=('created',)

    def __str__(self):
        return self.title

当创建好model之后,就可以开始编写Serializer类了。

Serializer是rest_framework中最简单的序列化基类,封装也是最低的。但是这个基类比较灵活,可以通过这个类来定制我们需要的序列化类。

实现这个类需要重写两个方法,create和update。

简单的理解,create方法对应我们在使用API的时候通过POST来访问的,因为通常通过POST来传递我们需要新建实例的数据。

update方法对应通过PUT/PATCH方法访问API,用来新建实例或者更新已存在的实例,这取决于数据库是否存在我们需要操作的实例。

from rest_framework import serializers
from .models import Article

class ArticleSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    author = serializers.CharField(max_length=20)
    title = serializers.CharField(max_length=30)
    content = serializers.CharField()
    created = serializers.DateTimeField(read_only=True)

    def create(self,validated_data):
        author = validated_data['author']
        title = validated_data['title']
        content = validated_data['content']
        return Article.objects.create(**validated_data)


    def update(self,instance,validated_data):
        instance.author=validated_data.get('author',instance.author)
        instance.title=validated_data.get('title',instance.title)
        instance.content=validated_data.get('content',instance.content)

        instance.save()
        return instance

在创建ArticleSerializer的时候,创建了一些字段,这些字段代表Serializer类在序列化的时候和model对应的字段。这些字段应该和model里定义的字段同名。

在定义的时候,指定了一些参数,这里只用了read_only,另外还有write_only,required,allow_null/allow_blank,label,help_text,style,error_messages

read_only:表示该字段只能用于API的输出,用户并不能直接指定该字段的值

write_only:这个就和read_only相反,需要用户指定该字段的值

required:该字段是必需的,不能为空

allow_null/allow_blank:该字段允许为null/空

label:标签,用于对字段显示设置

help_text:对字段进行解释的一段文本,用于提示

style:说明字段的类型

error_messages:字段出错时,信息提示


update方法中instancece参数是一个model实例,也可以是一个自定义类实例,其实model也就是一个类,只是在底层封装了一些ORM操作。

至此,自定义的ArticleSerializer类便完成了。下面就是写视图函数来实现API的访问

from django.shortcuts import render
from django.http import HttpResponse,JsonResponse
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
from .models import Article
from .serializer import ArticleSerializer
from django.views.decorators.csrf import csrf_exempt

# Create your views here.


@csrf_exempt
def article_list(request):
    if request.method=='GET':
        articles=Article.objects.all()
        serializer=ArticleSerializer(articles,many=True)
        return JsonResponse(serializer.data,safe=False)


    elif request.method=='POST':
        data=JSONParser().parse(request)
        serializer=ArticleSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data,status=201)
        return JsonResponse(serializer.errors,status=400)


@csrf_exempt
def article_detail(request,aid):

    #获取对应的文章
    try:
        article=Article.objects.get(id=aid)
    except:
        return HttpResponse(status=404)

    if request.method=='GET':
        serializer=ArticleSerializer(article)
        return JsonResponse(serializer.data,)

    if request.method=='PUT':
        data=JSONParser().parse(request)
        serializer=ArticleSerializer(data=data)

        if serializer.is_valid():
            print(serializer.validated_data)
            serializer.save()
            return JsonResponse(serializer.data)
        return JsonResponse(serializer.errors,status=400)

    if request.method=='PATCH':
        data=JSONParser().parse(request)
        serializer=ArticleSerializer(article,data=data,partial=True)

        if serializer.is_valid():
            print(serializer.validated_data)
            serializer.save()
            return JsonResponse(serializer.data)
        return JsonResponse(serializer.errors,status=400)

    if request.method=='DELETE':
        article.delete()
        return HttpResponse(status=204)

需要注意的一点就是这里希望没有csrf令牌客户端通过POST到这个视图函数,主要添加一个装饰器csrf_exempt.

article_detail方式为了能够向api传参,所以有一个aid参数,代表文章的id。

两个方法的思路总体就是先判断请求的方法。如果是GET,那么就从数据库读取article来序列化再返回到客户端。如果是POST/PUT/PATCH方式,就先需要反序列化传过来的数据,再通过Serializer类实现将数据转化为querydict类型数据格式,并且对数据进行验证。这里并没有做自定义的验证。如果需要自定义验证,需要在Serializer类里面实现。详情参考

article_detail方法中,在对PATCH方式进行处理时,我们希望能够实现部分更新,所有在实例化ArticleSerializer实例时,需要传入一个已存在的model实例。该段代码中已存在的model实例是根据aid查询得到的article。同时指定partial参数为True,表示允许部分更新。

视图函数写好之后,就是配置url

在创建的app目录下创建一个urls.py。我用的是django2.0,所以是通过path函数来配置的,如果是django1.x版本的是通过url函数来配置的

from django.urls import path
from . import views

urlpatterns=[
    path('article_list',views.article_list),
    path('article_detail/<int:aid>',views.article_detail)

]

django1.x版本

from django.conf.urls import url
from . import views

urlpatterns=[
    url(r'article_list',views.article_list),
    url(r'article_detail/(?P<aid>\d+)',views.article_detail)

]

然后再在项目urls.py文件中导入app的urls

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',include('tutorial.urls'))
]


运行

python manage.py runserver

然后通过httpie来访问api

httpie安装

pip install httpie


通过POST方式访问 localhost:8000/article_list 接口 来创建一篇文章



然后通过GET访问 localhost:8000/article_list 接口获取所有文章信息



通过GET方式获取指定文章的信息 localhost:8000/article_detail/8

 


通过PATCH方式修改指定文章的信息 



  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值