首页 > GAME > 游戏 > 正文

呼和浩特拔猜电子商务有限公司,湛江得献鬃电子有限公司,中卫踩舜电子有限公司

红孩儿早预备好了说辞,道:“我无事闲游天地,便遇着这个妖魔,他每几日便出来寻生人吃,那日见了我,便要抓去果腹。我自然要和他打一场,他敌不过我,便钻入水中去了,我决心要除了他,免得过路人受难,直候到今日他才现身。若不是这位……”红孩儿看了看八戒,不知如何称呼,“不是这位帮忙,恐怕我仍降他不住。”

爱得长久,因为懂得

现在那两扇大门还没有来的及连接起来,因此,无论是叶扬去那个世界,还是从那个世界回来。他们都是穿越了空间,而不是从那真正的通道里走出来的。
先天至宝乾坤鼎赐给了女娲就是最好的证明了,想想看刚才道祖已经赐下法宝给自己的弟子了,女娲得到了极品先天灵宝红绣球,不是至宝,但是威能却堪比至宝的山河社稷图。

“灵凝,不要再说了。”风魂猛然喝道。他的声音是那样的沉浑无力,就仿佛心口上的血早已流尽,纵然用尽力气,纵然想要呐喊,发出的却也只能是这种压抑到死的无奈。

django-rest-framework之序列化


前言:昨天学习了rest-framework序列化方面的知识,故写了博客记录一下。官网:http://www.django-rest-framework.org/tutorial/1-serialization/#working-with-serializers。

 

前后端分离:前台的开发和后台的开发分离开。这个方案的实现就是要借助API,API简单说就是开发人员提供编程接口被其他人调用,他们调用之后会返回数据供其使用。API的类型有多种,但是现在比较主流且实用的就是RESTful API。

 

一、开始

Okay, we"re ready to get coding. To get started, let"s create a new project to work with.首先创建一个Django项目。

cd ~
django-admin.py startproject tutorial
cd tutorial

Once that"s done we can create an app that we"ll use to create a simple Web API.接着创建一个APP

python manage.py startapp snippets

We"ll need to add our new snippets app and the rest_framework app to INSTALLED_APPS. Let"s edit the tutorial/settings.py file:修改全局配置文件。

INSTALLED_APPS = (
    ...
    "rest_framework",
    "snippets.apps.SnippetsConfig",
)

Please note that if you"re using Django <1.9, you need to replace snippets.apps.SnippetsConfig with snippets.

如果你使用的Django <1.9,则需要更换snippets.apps.SnippetsConfig为snippets

 

二、创建模型类

For the purposes of this tutorial we"re going to start by creating a simple Snippet model that is used to store code snippets(片段). Go ahead and edit the snippets/models.py file.

我们将首先创建一个Snippet用于存储代码片段的简单模型,编辑snippets/models.py文件。

from django.db import models

# Create your models here.

# pygments可以实现代码高亮 官网:http://pygments.org/
from pygments.lexers import get_all_lexers  # lexers:词法分析器
from pygments.styles import get_all_styles


LEXERS = [item for item in get_all_lexers() if item[1]]
LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS])
STYLE_CHOICES = sorted((item, item) for item in get_all_styles())


class Snippet(models.Model):
    created = models.DateTimeField(auto_now_add=True)  # 自动添加创建时间
    title = models.CharField(max_length=100, blank=True, default="")
    code = models.TextField()
    linenos = models.BooleanField(default=False)
    language = models.CharField(choices=LANGUAGE_CHOICES, default="python", max_length=100)
    style = models.CharField(choices=STYLE_CHOICES, default="friendly", max_length=100)

    class Meta:
        ordering = ("created",)  # 根据创建时间来排序

初始化并且同步到数据库:

python manage.py makemigrations snippets
python manage.py migrate

  

三、创建序列化类

The first thing we need to get started on our Web API is to provide a way of serializing(序列化) and deserializing(反序列化) the snippet instances into representations such as json. We can do this by declaring(声明) serializers that work very similar to Django"s forms. 

首先我要问你了,通常情况下,前端从调用后台API,API肯定需要返回数据给前端,那返回的数据是什么类型呢?

目前主流用的比较多的是JSON,可能有少部分还在用XML。

那我们在学习django-rest-framework时,有没有提供什么方法能够将数据实例信息自动转换为JSON?而且也可以将前端传给后台的JSON数据转换为python的数据类型(dict/list/set...)。当然有,序列化器(serializers)可以实现。首先你得声明(引入)序列化器,请看下面这个例子:

# 用Web API的第一件事是提供一种将代码片段实例序列化和反序列化为表示形式的方法json。
# 我们可以通过声明与Django表单非常相似的序列化器来做到这一点。在snippets命名的目录中创建一个文件,
# serializers.py并添加以下内容

from rest_framework import serializers
from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES


class SnippetSerializer(serializers.Serializer):
    # 序列化器类的第一部分定义了序列化/反序列化的字段。
    id = serializers.IntegerField(read_only=True)
    title = serializers.CharField(required=False, allow_blank=True, max_length=100)
    # 利用字段标志控制序列化器渲染到HTML页面时的的显示模板
    code = serializers.CharField(style={"base_template": "textarea.html"})
    linenos = serializers.BooleanField(required=False)
    language = serializers.ChoiceField(choices=LANGUAGE_CHOICES, default="python")
    style = serializers.ChoiceField(choices=STYLE_CHOICES, default="friendly")

    def create(self, validated_data):
        """
        The create() and update() methods define how fully fledged instances are created
        or modified when calling serializer.save()
        Create and return a new `Snippet` instance, given the validated data.
        给定经过验证的数据,创建并返回一个新的 Snippet 实例
        """
        return Snippet.objects.create(**validated_data)

    def update(self, instance, validated_data):
        """
        Update and return an existing `Snippet` instance, given the validated data.
        给定经过验证的数据,更新并返回一个已经存在的 Snippet 实例
        """
        instance.title = validated_data.get("title", instance.title)
        instance.code = validated_data.get("code", instance.code)
        instance.linenos = validated_data.get("linenos", instance.linenos)
        instance.language = validated_data.get("language", instance.language)
        instance.style = validated_data.get("style", instance.style)
        instance.save()  # 更新
        return instance

序列化器类的第一部分定义了序列化/反序列化的字段。该create()update()方法分别定义实例如何创建和更新。

关于下面这行代码:

code = serializers.CharField(style={"base_template": "textarea.html"})

暂时需要知道的就是它的功能是控制序列化器渲染到HTML页面时的的显示模板,至于为什么要这样做,是因为这对于控制如何显示可浏览的API特别有用,这将在后面的文章中看到。

实际上也可以通过使用ModelSerializer来节省自己的时间,我们稍后会看到,接下来看看序列化器的具体作用。

 

四、使用序列化器

在我们进一步了解之前,我们将熟悉使用我们新的Serializer类。我们进入Django shell:

python manage.py shell

接下来的操作就和学习Django的ORM时那样,创建并保存Snippet模型实例:

from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser

snippet = Snippet(code="foo = "bar"
")
snippet.save()

snippet = Snippet(code="print "hello, world"
")
snippet.save()

这个时候查看数据库就会发现相关的表中已经多了两行数据,就是我们刚才创建的数据: 

我们现在有几个片段实例可以玩。我们来看看序列化这些实例之一

serializer = SnippetSerializer(snippet)
serializer.data
# {"id": 2, "title": u"", "code": u"print "hello, world"
", "linenos": False, "language": u"python", "style": u"friendly"}

At this point we"ve translated the model instance into Python native datatypes. 

从上面的代码,可以看到,我们已经将model的实例信息转换为python原生的数据类型,即字典。

To finalize the serialization process we render the data into json.

为了完成序列化过程,我们将数据转换成json

content = JSONRenderer().render(serializer.data)
content
# "{"id": 2, "title": "", "code": "print \"hello, world\"\n", "linenos": false, "language": "python", "style": "friendly"}"

这里已经出现了json格式,也就是说这个json格式的数据就是要展示在某个URL上,大概可以感觉到,等下我们在访问某个URL时,会返回上面这堆数据供你使用,这其实就完成了一个序列化的过程,也可以看出客户端的功能雏形。

序列化是为了返回json格式的数据给客户端查看和使用数据,那么当客户端需要修改、增加或者删除数据时,就要把过程反过来了,也就是反序列化,把客户端提交的json格式的数据反序列化。

反序列化是类似的。首先我们将一个流解析为Python本机数据类型...

from django.utils.six import BytesIO

stream = BytesIO(content)
data = JSONParser().parse(stream)

...then we restore those native datatypes into a fully populated object instance.

检查数据是否有误,再保存数据:

serializer = SnippetSerializer(data=data)
serializer.is_valid()
# True
serializer.validated_data
# OrderedDict([("title", ""), ("code", "print "hello, world"
"), ("linenos", False), ("language", "python"), ("style", "friendly")])
serializer.save()
# <Snippet: Snippet object>

这个时候查看数据库又多了一条数据:

We can also serialize querysets instead of model instances. To do so we simply add a many=True flag to the serializer arguments.

我们也可以序列化查询集而不是模型实例。为此,我们只需要为serializer参数添加一个标志many=True

serializer = SnippetSerializer(Snippet.objects.all(), many=True)
serializer.data
# [OrderedDict([("id", 1), ("title", u""), ("code", u"foo = "bar"
"), ("linenos", False), ("language", "python"), ("style", "friendly")]), OrderedDict([("id", 2), ("title", u""), ("code", u"print "hello, world"
"), ("linenos", False), ("language", "python"), ("style", "friendly")]), OrderedDict([("id", 3), ("title", u""), ("code", u"print "hello, world""), ("linenos", False), ("language", "python"), ("style", "friendly")])]

 

 

五、使用 ModelSerializers

在上面的SnippetSerializer类中,我们继承的是serializers.Serializer类,可以看到SnippetSerializer类中有很多代码其实是和models.py中的Snippet模型类似一样的,所以这里我们可以改进一下。就像在Django中提供了Form类和ModelForm类一样,django-rest-framework为我们提供了Serializer类和ModelSerializer类。利用它可以让我们的代码简洁很多,修改serializers.py:

# Our SnippetSerializer class is replicating a lot of information that"s also contained in the Snippet model.
# It would be nice if we could keep our code a bit more concise.
class SnippetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Snippet
        fields = ("id", "title", "code", "linenos", "language", "style")

One nice property that serializers have is that you can inspect(检查/查看) all the fields in a serializer instance, by printing its representation. Open the Django shell with python manage.py shell, then try the following:

序列化器具有的一个不错的属性是可以通过打印其表示来检查序列化器实例中的所有字段。打开Django shell python manage.py shell,然后尝试以下操作:

from snippets.serializers import SnippetSerializer
serializer = SnippetSerializer()
print(repr(serializer))
# SnippetSerializer():
#    id = IntegerField(label="ID", read_only=True)
#    title = CharField(allow_blank=True, max_length=100, required=False)
#    code = CharField(style={"base_template": "textarea.html"})
#    linenos = BooleanField(required=False)
#    language = ChoiceField(choices=[("Clipper", "FoxPro"), ("Cucumber", "Gherkin"), ("RobotFramework", "RobotFramework"), ("abap", "ABAP"), ("ada", "Ada")...
#    style = ChoiceField(choices=[("autumn", "autumn"), ("borland", "borland"), ("bw", "bw"), ("colorful", "colorful")...

记住,ModelSerializer类不会做任何特别神奇的事情,它们只是创建序列化器类的快捷方式:

  • 一组自动确定的字段。
  • 简单的默认实现create()和update()方法。

 

六、编写常规的Django视图

接下来要做的就是使用我们的新的Serializer类编写一些API视图。编辑snippets/views.py:

from django.shortcuts import render

# Create your views here.
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 snippets.models import Snippet
from snippets.serializers import SnippetSerializer


@csrf_exempt
def snippet_list(request):
    """
    because we want to be able to POST to this view from clients
    that won"t have a CSRF token we need to mark the view as csrf_exempt
    List all code snippets, or create a new snippet.
    """
    if request.method == "GET":
        snippets = Snippet.objects.all()
        serializer = SnippetSerializer(snippets, many=True)
        return JsonResponse(serializer.data, safe=False)

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


@csrf_exempt
def snippet_detail(request, pk):
    """
    Retrieve, update or delete a code snippet.
    """
    try:
        snippet = Snippet.objects.get(pk=pk)
    except Snippet.DoesNotExist:
        return HttpResponse(status=404)

    if request.method == "GET":
        serializer = SnippetSerializer(snippet)
        return JsonResponse(serializer.data)

    elif request.method == "PUT":
        data = JSONParser().parse(request)
        serializer = SnippetSerializer(snippet, data=data)
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data)
        return JsonResponse(serializer.errors, status=400)

    elif request.method == "DELETE":
        snippet.delete()
        return HttpResponse(status=204)

上面的代码都比较好理解,定义了不同http动作时后台不同的操作,在这里也体现了restful API的理念。

because we want to be able to POST to this view from clients that won"t have a CSRF token we need to mark the view as csrf_exempt.

因为我们希望能够从不具有CSRF令牌的客户端对此视图进行POST,因此我们需要给视图加个一个装饰器csrf_exempt

 

为了让视图函数被调用,那当然需要设计一下url了,这里的处理和平时Django开发时是一样的。首先创建snippets/urls.py

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

urlpatterns = [
    url(r"^snippets/$", views.snippet_list),
    url(r"^snippets/(?P<pk>[0-9]+)/$", views.snippet_detail),
]

We also need to wire up the root urlconf, in the tutorial/urls.py file, to include our snippet app"s URLs.

from django.conf.urls import url, include

urlpatterns = [
    url(r"^", include("snippets.urls")),
]

  

七、对API进行测试

完成了上面那些工作后,就可以开始测试了,退出shell模式并启动服务器,根据我们刚才设计的url发送请求,需要先安装httpie模块:

pip install httpie

然后在命令行窗口访问,效果如下: 

也可以访问指定id的数据: 

 当然了,也可以直接在浏览器查看,直接输入那个URL就可以了: 

 

当前文章:http://mabebox.com/news/2018112366141/index.html

发布时间:2019-03-26 03:15:46

打破水银温度计了怎么办 那么,葡萄酒 你的陨落,让世界失去了一位传奇---克里斯托弗·李 怪物契约 爱上我,还是爱上我优越的条件 触目惊心的当代“官赌” 没吃到香蕉的猴子 一篇文章看懂Android学习最佳路线

长期通过微博、微信、知乎接收碎片化知识有什么弊端? 历史,让我们看见 压抑与节制 科普离乳的方法 2011成长营:参加国际大赛的经历 罗李华简谈2016年十二生肖运势 原创:面对灾难最好的帮助—倾听篇 跳在乐趣消失前 戒除心毒,便可成就未来。 家长“说教”是怎样毁人不倦的? 罗李华:水瓶座2016年运势 没有仪式感的爱情,不会长久 由租房话题说开了跑题话语。。。 欧美艳照门:你看见的只是冰山一角 一下剩出七个 一下剩出七个 赤子孤独了,会创造一个世界——纪念傅雷夫妇 起名专家罗李华谈起名之禁忌 何谓好名字

编辑:伯安杜海


声明:所发布的内容均来源于互联网,目的在于传递信息,但不代表本站赞同其观点及立场,版权归属原作者,如有侵权请联系删除。
所有的暗恋其实都是明恋

当父母在做这十件事时,请让孩子看见

李嘉诚:我一直都在,从未离开