Django笔记 Django REST Framework实现Web API 1
来源:互联网 发布:找客户的app软件 编辑:程序博客网 时间:2024/06/10 06:35
前言
本文介绍如何使用Django的REST框架来迅速开发WEBAPI。
Django REST Framework
Django REST Framework可以在Django的基础上迅速实现API,并且自身还带有WEB的测试页面,可以方便的测试自己的API。
RESTful API
首先简单的介绍下RESTful API的意思。
WebAPI ≠ RESTful
所有通过HTTP/HTTPS来通信的API不一定都是RESTful。RESTful是一种API的设计概念,遵守它可以实现简单但良好的易于扩展的API。
Model和 1对1的API
RESTful API的特点在于和Model是1対1的关系。1个API对应一个Model,实现对一个Model的查询,添加,删除等操作。
手机APP需要少量请求就能获得足够的信息,并且能完成多个业务操作,这种设计方式也许不能满足要求。但从规则简单,独立性,等考虑,这种设计方法非常容易实现。
GET, POST, PUT, DELETE
RESTful主要有4个HTTP方法。
GET /entries
获取一览
POST /entries
添加
GET /entries/
更新特定的数据
DELTE /entries/$entry_id
删除特定的数据
POST与PUT的区别在于,有没有entry_id,没有是添加用POST,有了是更新,用PUT。
开始
环境
OS: OS X(El Capitan)
Python: Python 3.5
Django: 1.9
django-filter: 0.11.0
djangorestframework: 3.3.1
建立工程
安装库
pip install djangopip install djangorestframeworkpip install django-filter
生成APP
django-admin startproject django_rest_framework_testcd django_rest_framework_test/python manage.py startapp blog# 目录结构.└── django_rest_framework_test ├── blog │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ ├── models.py │ ├── tests.py │ └── views.py ├── django_rest_framework_test │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── manage.py
定义Model
from django.db import modelsclass User(models.Model): name = models.CharField(max_length=32) mail = models.EmailField()class Entry(models.Model): STATUS_DRAFT = "draft" STATUS_PUBLIC = "public" STATUS_SET = ( (STATUS_DRAFT, "草稿"), (STATUS_PUBLIC, "公开"), ) title = models.CharField(max_length=128) body = models.TextField() created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) status = models.CharField(choices=STATUS_SET, default=STATUS_DRAFT, max_length=8) author = models.ForeignKey(User, related_name='entries')
构建DB
# 添加程序 blogINSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'blog',]
然后同步数据结构,默认使用Sqlite3.
python manage.py makemigrationspython manage.py migrate
这样默认生成db.sqlite3,并自动生成blog的表。
启动确认下
# 创建管理用户python manage.py createsuperuser Username (leave blank to use 'kimihiro_n'): dev Email address: Password: Password (again): Superuser created successfully.# 启动服务器python manage.py runserver
从http://localhost:8000/admin
登入管理画面
这个是Django的管理画面。想要显示刚才添加的两个Model,需要在下面添加如下。
blog/admin.pyfrom django.contrib import adminfrom .models import User, Entry@admin.register(User)class UserAdmin(admin.ModelAdmin): pass@admin.register(Entry)class Entry(admin.ModelAdmin): pass
管理画面如图。
这里可以编辑blog的内容了。
使用Djagno REST Framework
添加APP REST Framework
django_rest_framework_test/settings.pyINSTALLED_APPS = ( ... 'blog', 'rest_framework',)
在配置文件的INSTALLED_APPS中添加rest_framework。
生成REST API最少需要定义下面3个。
- Serializer
- ViewSet
- URL pattern
简单来说,Serializer是将「Model序列化」,ViewSet是API的应答器,URL Pattern定义了URL的路由。
定义Serialzier
blog/serializer.py# coding: utf-8from rest_framework import serializersfrom .models import User, Entryclass UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ('name', 'mail')class EntrySerializer(serializers.ModelSerializer): class Meta: model = Entry fields = ('title', 'body', 'created_at', 'status', 'author')
需要继承serializers.ModelSerializer, fields为API想要得到的字段。
定义ViewSet
blog/views.py# coding: utf-8import django_filtersfrom rest_framework import viewsets, filtersfrom .models import User, Entryfrom .serializer import UserSerializer, EntrySerializerclass UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all() serializer_class = UserSerializerclass EntryViewSet(viewsets.ModelViewSet): queryset = Entry.objects.all() serializer_class = EntrySerializer
queryset设置为Model的queryset,serializer_class设置为刚才定义的serializer。
定义URL pattern
django_rest_framework_test/urls.py# coding: utf-8from django.conf.urls import url, includefrom django.contrib import adminfrom blog.urls import router as blog_routerurlpatterns = [ url(r'^admin/', admin.site.urls), #include blog.urls url(r'^api/', include(blog_router.urls)),]
blog/urls.py# coding: utf-8from rest_framework import routersfrom .views import UserViewSet, EntryViewSetrouter = routers.DefaultRouter()router.register(r'users', UserViewSet)router.register(r'entries', EntryViewSet)
这样,
GET /api/users/ 可以得到User的 一览,
GET /api/entries/可以得到Entry的 一览
另外POST和通过ID的操作也可以实现。
测试API
python manage.py runserver
启动后,可以通过自带的Web平台进行测试。
也可以通过命令curl http://localhost:8000/api/来测试,这里返回的是Json格式。在URL上加上?format=json的话,浏览器也会强制返回JSON格式。
自定义API
真正运用的时候,可能需要对抽选进行过滤。另外比如
将关系表数据同时获取
例如下面的数据
{ "title": "Hello, Django REST API!!", "body": "<script>alert(\"hello\");</script>", "created_at": "2015-12-09T05:59:46.200277Z", "status": "draft", "author": 1}
返回的是author的ID。如果这样下次还要通过 /api/users/1再次请求User的数据。这样效率并不好,现在我们想获得下面的数据。
{ "title": "Hello, Django REST API!!", "body": "<script>alert(\"hello\");</script>", "created_at": "2015-12-09T05:59:46.200277Z", "status": "draft", "author": { "name": "Alice", "mail": "alice@example.com" }}
在Serializer里把author的部分,再次定义一下。
blog/serializer.py…class EntrySerializer(serializers.ModelSerializer): # author的serializer author = UserSerializer() class Meta: model = Entry fields = ('title', 'body', 'created_at', 'status', 'author')
EntrySerializer 重新定义author,这样获取的时候会同时获得User信息。
其他的自定义方法请参照 http://www.django-rest-framework.org/api-guide/serializers/
分页
现在获取数据都是全件获取,数据量非常大的时候,需要对数量进行限制。
django_rest_framework_test/settings.pyREST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', 'PAGE_SIZE': 2}
设置需要全局设置。在配置文件里,定义REST_FRAMEWORK,设置DEFAULT_PAGINATION_CLASS和PAGE_SIZE。
这样API会出现offset(开始位置)和limit(限制件数,
default=PAGE_SIZE)等参数。
{ "count": 4, "next": "http://localhost:8000/api/entries/?limit=2&offset=2", "previous": null, "results": [ { "id": 1, "title": "Hello, Django REST Framework!!", "body": "Hello!", "created_at": "2015-12-12T11:55:22.310203Z", "status": "draft", "author": 1 }, { "id": 2, "title": "The Zen of Python", "body": "The Zen of Python, by Tim Peters\r\n\r\nBeautiful is better than ugly.\r\nExplicit is better than implicit.\r\nSimple is better than complex.\r\nComplex is better than complicated.\r\nFlat is better than nested.\r\nSparse is better than dense.\r\nReadability counts.\r\nSpecial cases aren't special enough to break the rules.\r\nAlthough practicality beats purity.\r\nErrors should never pass silently.\r\nUnless explicitly silenced.\r\nIn the face of ambiguity, refuse the temptation to guess.\r\nThere should be one-- and preferably only one --obvious way to do it.\r\nAlthough that way may not be obvious at first unless you're Dutch.\r\nNow is better than never.\r\nAlthough never is often better than *right* now.\r\nIf the implementation is hard to explain, it's a bad idea.\r\nIf the implementation is easy to explain, it may be a good idea.\r\nNamespaces are one honking great idea -- let's do more of those!", "created_at": "2015-12-12T11:56:32.854278Z", "status": "draft", "author": 2 } ]}
next,previous都会带有URL,非常的方便。
其他方式,参照 http://www.django-rest-framework.org/api-guide/pagination/
筛选
如果想通过author来筛选Entry时。
django_rest_framework_test/settings.pyREST_FRAMEWORK = { 'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',)}
在配置文件里添加DEFAULT_FILTER_BACKENDS。和分页所设置的是同一个字典。
class EntryViewSet(viewsets.ModelViewSet): queryset = Entry.objects.all() serializer_class = EntrySerializer filter_fields = ('author', 'status')
然后在ViewSet里设置filter_fields。这样就可以通过author和status来筛选。
API后面为?author=1,就会抽选User id=1的blog。?status=public会抽选已经公开的Blog
其他筛选方法参照 http://www.django-rest-framework.org/api-guide/filtering/
参考URL
http://qiita.com/kimihiro_n/items/86e0a9e619720e57ecd8
http://www.django-rest-framework.org/
http://www.slideshare.net/unsolublesugar/res-tful
http://qiita.com/KojiOhki/items/5be98eeae72dca2260bc
http://racchai.hatenablog.com/entry/2016/04/12/Django_REST_framework_%E8%B6%85%E5%85%A5%E9%96%80
- Django笔记 Django REST Framework实现Web API 1
- Django REST framework API
- Django REST framework API开发
- Django rest framework 学习笔记
- django Rest Framework 系列 1
- Django Rest FrameWork 全部API简述
- 利用 Django REST framework 编写 RESTful API
- [django]禁用 Django Rest Framework 的 Browsable API
- Django REST framework实现关键词检索
- Django笔记 Django REST framework的Serializer 2
- Django REST framework
- Django REST framework
- Django-Rest-Framework 教程
- django rest framework Serializer
- Django Rest Framework
- django rest framework quickstart
- Django rest framework
- Django rest framework --- Routers
- 1
- 图像采集处理之DDR内存分配
- iOS-IM From XMPP.1 初识XMPP
- Java---MD5Util加密
- 基于annotation的hibernate主键生成策略(转)
- Django笔记 Django REST Framework实现Web API 1
- Java enum的用法详解
- AngularJS带给你一个简单完善的Demo
- whuoj1574 第K小数
- CocoaPods安装和使用--(版本依赖写的特别的清楚。。大于和小于等版本号的写法)
- POJ题目分类
- Subsets II @Leetcode
- 前端程序员:月薪5K到5万,我干了啥
- 浅析@synthesize与@dynamic的最本质区别