(点击
上方蓝字
,快速关注我们)
来源:伯乐在线专栏作者 - 王海波
如有好文章投稿,请点击 → 这里了解详情
最近学习了REST方面的知识,了解了REST 的基础、API 的设计规则等等。
在Django中,不需要自己去设计每一个API,因为djangorestframwork帮我们做了一些工作。其实设计Django REST API的框架不少,但是djangorestframwork风格更像Django,与django的集成度更高,更易上手。该框架分为model, serializer, views三层,支持权限许可等功能。
现在就边做边学习这方面的知识。 首先是准备工作: 1、安装djangorestframwork pip install djangorestframework; 2、安装django-filter;
配置:
-
在INSTALLED_APPS中添加: ‘rest_framwork’
-
设置 REST_FRAMEWORK
REST_FRAMEWORK
=
{
# Use Django's standard
django.contrib.auth
permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES'
:
[
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
,
],
'DEFAULT_PAGINATION_CLASS'
:
'rest_framework.pagination.LimitOffsetPagination'
,
'PAGE_SIZE'
:
2
,
'DEFAULT_FILTER_BACKENDS'
:
(
'rest_framework.filters.DjangoFilterBackend'
,)
}
在上面设置了权限,设置了结果分页,设置了过滤器。
上面配置完成,开始写代码。
一、Model就是数据库定义的模型本身
Model有article,user,category三个
class
Category
(
models
.
Model
)
:
name
=
models
.
CharField
(
max_length
=
150
,
unique
=
True
,
verbose_name
=
u
'类名'
)
alias
=
models
.
CharField
(
max_length
=
150
,
verbose_name
=
u
'英文名称'
)
status
=
models
.
IntegerField
(
default
=
0
,
choices
=
STATUS
.
items
(),
verbose_name
=
u
'状态'
)
#Automatically set the field to now when the object is first created.
create_time
=
models
.
DateTimeField
(
auto_now_add
=
True
)
parent
=
models
.
ForeignKey
(
'self'
,
default
=
None
,
blank
=
True
,
null
=
True
,
verbose_name
=
u
'上级分类'
)
class
Article
(
models
.
Model
)
:
title
=
models
.
CharField
(
max_length
=
150
,
unique
=
True
,
verbose_name
=
u
'标题'
)
alias
=
models
.
CharField
(
max_length
=
150
,
verbose_name
=
u
'英文标题'
)
content
=
models
.
TextField
(
verbose_name
=
u
'正文'
)
#when editing article,content_html will be saved automatically from content.so it can be blank
content_html
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
u
'正文html格式'
)
abstract
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
u
'摘要'
)
read_times
=
models
.
IntegerField
(
default
=
0
,
verbose_name
=
u
'阅读次数'
)
tags
=
models
.
CharField
(
max_length
=
100
,
verbose_name
=
u
'标签'
,
help_text
=
'用逗号隔开'
)
status
=
models
.
IntegerField
(
default
=
0
,
choices
=
STATUS
.
items
(),
verbose_name
=
u
'文章状态'
)
#Automatically set the field to now when the object is first created
create_time
=
models
.
DateTimeField
(
auto_now_add
=
True
)
pub_time
=
models
.
DateTimeField
(
default
=
datetime
.
now
())
#Automatically set the field to now every time the object is saved.
update_time
=
models
.
DateTimeField
(
auto_now
=
True
)
author
=
models
.
ForeignKey
(
User
,
verbose_name
=
u
'作者'
)
category
=
models
.
ForeignKey
(
Category
,
verbose_name
=
u
'分类'
)
access
=
models
.
IntegerField
(
default
=
100
,
choices
=
ACCESS
.
items
(),
verbose_name
=
u
'文章权限,公开或者私人可见'
)
User Model是Django自带的Model。
二、序列化Serializer
摘自官网:
Serializers allow complex data such as querysets and model instances to be converted to native Python datatypes that can then be easily rendered into JSON, XML or other content types. Serializers also provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data.
The serializers in REST framework work very similarly to Django’s Form and ModelForm classes. We provide a Serializer class which gives you a powerful, generic way to control the output of your responses, as well as a ModelSerializer class which provides a useful shortcut for creating serializers that deal with model instances and querysets.
从以上文字可以看出,serializer的目的是将查询集或模型实例转化为Python数据类型,从而很方便得转变为Json,XML等多种格式。
我的项目中的Serializer设计:
from rest_framework import serializers
from
.
models import
Category
,
Article
from
django
.
contrib
.
auth
.
models import User
from
django
.
forms import widgets
class
CategorySerializer
(
serializers
.
ModelSerializer
)
:
# Serializers define the API representation.
class
Meta
:
model
=
Category
fields
=
(
'id'
,
'name'
,
'alias'
,
'parent'
,
'create_time'
,
'status'
)
class
UserSerializer
(
serializers
.
ModelSerializer
)
:
class
Meta
:
model
=
User
fields
=
(
'username'
,
'email'
,
'last_login'
)
class
ArticleSerializer
(
serializers
.
ModelSerializer
)
:
category
=
CategorySerializer
()
author
=
UserSerializer
()
class
Meta
:
model
=
Article
fields
=
(
'title'
,
'content'
,
'author'
,
'category'
,
'pub_time'
)
在上面每个序列器都指定了Model,这样会自动生成序列化字段,这样比较方便。 在ArticleSerializer中,加入了author和category的序列化,这样做是因为当我们浏览article的信息时。会直接显示author和category的具体信息,否则就只是author和category的id。
三、View:
主要使用viewset。和route ViewSet为我们提供了默认的URL结构, 使得我们能更专注于API本身。而Route能够轻松的帮我们实现URL和ViewSet之间的关联。 源代码:
views
.
py
class
CategoryViewset
(
viewsets
.
ModelViewSet
)
:
"""
This viewset automatically provides `list`, `create`, `retrieve`,
`update` and `destroy` actions.
Additionally we also provide an extra `highlight` action.
"""
queryset
=
Category
.
objects
.
all
()
serializer_class
=
CategorySerializer
def perform_create
(
self
,
serializer
)
:
serializer
.
save
()
class
UserViewset
(
viewsets
.
ModelViewSet
)
:
queryset
=
User
.
objects
.
all
()
permission_classes
=
(
IsAdminUser
,)
serializer_class
=
UserSerializer
class
ArticleViewset
(
viewsets
.
ModelViewSet
)
:
"""
the viewset let us can get data from api url
like:curl - H 'application/json;indent=4' http://localhost:8080/api/articles/
of course,we can get some author's article through:
http://localhost:8080/api/articles/?author=2(author's id)
Generally,people like to see json data,so when visit by browser,you should add
?format=json ,that is,http://localhost:8080/api/articles/?format=json
"""
queryset
=
Article
.
objects
.
all
()
serializer_class
=
ArticleSerializer
filter_backends
=
(
filters
.
DjangoFilterBackend
,)
filter_fields
=
(
'author'
,
'category'
,
'access'
,
'status'
)
上面使用了ModelSet是有原因的,因为它自动提供delete,create,update,list等操作,即增删该查等操作。
其次说下filter,一般都用默认的DjangoFilterBackend,此外rest-framework 提供了几个原生的 filter:
SearchFilter
filter_backends = (filters.SearchFilter,) search_fields = (‘username’, ’email’) # 指定搜索的域
请求 http://example.com/api/users?search=russell。
OrderingFilter
filter_backends = (filters.OrderingFilter,) ordering_fields = (‘username’, ’email’)
请求 http://example.com/api/users?ordering=account,-username。
再说下权限。
rest_framework 中提供了七种权限
AllowAny
# 无限制
IsAuthenticated
# 登陆用户
IsAdminUser
# Admin 用户
IsAuthenticatedOrReadOnly
# 非登录用户只读
DjangoModelPermissions
# 以下都是根据 Django 的 ModelPremissions
DjangoModelPermissionsOrAnonReadOnly
DjangoObjectPermissions
把源码拿出来:
class
IsAuthenticated
(
BasePermission
)
:
"""
Allows access only to authenticated users.
"""
def has_permission
(
self
,
request
,
view
)
:
return
request
.
user
and
request
.
user
.
is_authenticated
()
class
IsAdminUser
(
BasePermission
)
:
"""
Allows access only to admin users.
"""
def has_permission
(
self
,
request
,
view
)
: