一、搭建环境
#新建虚拟环境 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"}]