• django-rest-framework笔记-序列化篇


    一、搭建环境

    #新建虚拟环境
    virtualenv venv
    source venv/bin/activate
    #在虚拟环境中安装项目依赖库
    cat requirements.txt
    
    coreapi==2.3.1
    django==1.11.4
    django-filter==1.0.4
    django-crispy-forms==1.6.1
    django-guardian==1.4.9
    httpie-0.9.9
    Markdown==2.6.8
    Pygments==2.2.0
    
    pip install -r requirements.txt

    二、创建项目,配置

    #新建项目
    django-admin startproject tutorial
    #创建应用
    cd tutorial
    python manage.py startapp snippets

    配置:

    #将我们新建的snippets app和rest_framework添加到INSTALLED_APPS
    INSTALLED_APPS = [
        ...
        'rest_framework',
        'snippets.apps.SnippetsConfig' #Djangp<1.9 替换为snippets
    ]
    
    #数据库配置
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'rest', # database
            'USER': 'root',
            'PASSWORD': 'root',
            'HOST': '192.168.1.115',
            'OPTIONS': {
                'autocommit': True,
                'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
            }
        }
    }

    注:如果mysql-python安装不上去,可以使用pymysql替代

    在tutorial包中的__init__.py 将pymysql转为mysql-python

    try:
        import pymysql
        pymysql.install_as_MySQLdb()
    except ImportError:
        pass

    三、模型

    编辑文件snippets/models.py

    from django.db import models
    from pygments.lexers import get_all_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

    四、序列化

    新建snippets/serializers.py文件

    #!/usr/bin/env python
    # coding:utf-8
    from __future__ import absolute_import, print_function, division
    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)
        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):
            """
            Create and return a new `Snippet` instance, given the validated data.
            """
            return Snippet.objects.create(**validated_data)
    
        def update(self, instance, validated_data):
            """
            Update and return an existing `Snippet` instance, given the validated data.
            """
            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

    注:就像django里的Form和ModelForm一样,序列化也有Serializer和ModelSerializer

    #!/usr/bin/env python
    # coding:utf-8
    from __future__ import absolute_import, print_function, division
    from rest_framework import serializers
    from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES
    
    #已实现create和update
    class SnippetSerializer(serializers.ModelSerializer): class Meta: model
    = Snippet fields = ("id", "title", "code", "linenos", "language", "style")
    In [1]: from snippets.serializers import  SnippetSerializer
    
    In [2]: serializer = SnippetSerializer()
    
    In [3]: 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=[('abap', 'ABAP'), ('abnf', 'ABNF'), ('ada', 'Ada'), ...], required=False)
        style = ChoiceField(choices=[('abap', 'abap'), ..., ('xcode', 'xcode')], required=False)

    五、视图

    编辑snippets/views.py

    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    # 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):
        """
        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)

    六、路由

    创建app路由

    新建文件snippets/urls.py

    #!/usr/bin/env python
    # coding:utf-8
    from __future__ import absolute_import, print_function, division
    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),
    ]

    编辑项目路由(tutorial/urls.py)

    """rest_demo URL Configuration
    
    The `urlpatterns` list routes URLs to views. For more information please see:
        https://docs.djangoproject.com/en/1.11/topics/http/urls/
    Examples:
    Function views
        1. Add an import:  from my_app import views
        2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
    Class-based views
        1. Add an import:  from other_app.views import Home
        2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
    Including another URLconf
        1. Import the include() function: from django.conf.urls import url, include
        2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
    """
    from django.conf.urls import url, include
    from django.contrib import admin
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^', include('snippets.urls')),
    ]

    七、插入数据

    python manage.py shell

    In [1]: from snippets.models import  Snippet
    
    In [2]: from snippets.serializers import  SnippetSerializer
    
    In [3]: from rest_framework.renderers import  JSONRenderer
    
    In [4]: from rest_framework.parsers import  JSONParser
    
    In [5]: snippet = Snippet(code='foo = "bar"
    ')
    
    In [6]: snippet.save()
    
    In [7]: snippet = Snippet(code='print "Hello, Django-restframework"
    ')
    
    In [8]: snippet.save()
    
    In [9]: serializer = SnippetSerializer(snippet)
    
    In [10]: serializer.data
    Out[10]:
    ReturnDict([('id', 2),
                ('title', u''),
                ('code', u'print "Hello, Django-restframework"
    '),
                ('linenos', False),
                ('language', 'python'),
                ('style', 'friendly')])
    
    In [11]: content = JSONRenderer().render(serializer.data)
    
    In [12]: content
    Out[12]: '{"id":2,"title":"","code":"print \"Hello, Django-restframework\"\n"
    ,"linenos":false,"language":"python","style":"friendly"}'

    八、测试-httpie

    # http http://127.0.0.1:8000/snippets/
    HTTP/1.0 200 OK
    Content-Length: 248
    Content-Type: application/json
    Date: Thu, 17 Aug 2017 15:00:56 GMT
    Server: WSGIServer/0.1 Python/2.7.12
    X-Frame-Options: SAMEORIGIN
    
    [
        {
            "code": "foo = "bar"
    ",
            "id": 1,
            "language": "python",
            "linenos": false,
            "style": "friendly",
            "title": ""
        },
        {
            "code": "print "Hello, Django-restframework"
    ",
            "id": 2,
            "language": "python",
            "linenos": false,
            "style": "friendly",
            "title": ""
        }
    ]

    浏览器访问http://127.0.0.1:8000/snippets/

    [{"id": 1, "title": "", "code": "foo = "bar"
    ", "linenos": false, "language": "python", "style": "friendly"}, {"id": 2, "title": "", "code": "print "Hello, Django-restframework"
    ", "linenos": false, "language": "python", "style": "friendly"}]
  • 相关阅读:
    网络模块axios的简单应用
    UWP App国际化的两种实现
    C# 显示函数调用方的详细信息
    UWP SVG 转 Glyph
    UWP 区分设备类型
    Flutter 星标已正式超过React Native
    查看Github星标排行榜
    博客园部分非公开api
    模块化(零):综述
    模块化一:提取模块
  • 原文地址:https://www.cnblogs.com/jachin/p/7384916.html
Copyright © 2020-2023  润新知