专栏名称: Python开发者
人生苦短,我用 Python。伯乐在线旗下账号「Python开发者」分享 Python 相关的技术文章、工具资源、精选课程、热点资讯等。
目录
相关文章推荐
Python爱好者社区  ·  DeepSeek创始人梁文锋个人履历 ·  2 天前  
Python爱好者社区  ·  离谱!下载DeepSeek最高判刑20年? ·  昨天  
Python开发者  ·  请立即拿下软考证书(政策风口) ·  3 天前  
Python爱好者社区  ·  推荐我的抖音变现俱乐部! ·  4 天前  
Python爱好者社区  ·  张雪峰公司今年的年终奖... ·  4 天前  
51好读  ›  专栏  ›  Python开发者

Django 中 REST API 的设计

Python开发者  · 公众号  · Python  · 2017-05-03 20:06

正文

(点击 上方蓝字 ,快速关注我们)


来源:伯乐在线专栏作者 - 王海波

如有好文章投稿,请点击 → 这里了解详情


最近学习了REST方面的知识,了解了REST 的基础、API 的设计规则等等。


在Django中,不需要自己去设计每一个API,因为djangorestframwork帮我们做了一些工作。其实设计Django REST API的框架不少,但是djangorestframwork风格更像Django,与django的集成度更高,更易上手。该框架分为model, serializer, views三层,支持权限许可等功能。


现在就边做边学习这方面的知识。 首先是准备工作: 1、安装djangorestframwork pip install djangorestframework; 2、安装django-filter;


配置:


  1. 在INSTALLED_APPS中添加: ‘rest_framwork’

  2. 设置 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 ) :







请到「今天看啥」查看全文


推荐文章
Python爱好者社区  ·  DeepSeek创始人梁文锋个人履历
2 天前
Python爱好者社区  ·  离谱!下载DeepSeek最高判刑20年?
昨天
Python开发者  ·  请立即拿下软考证书(政策风口)
3 天前
Python爱好者社区  ·  推荐我的抖音变现俱乐部!
4 天前
Python爱好者社区  ·  张雪峰公司今年的年终奖...
4 天前
qsqs33  ·  哥们你敢说你不怕老婆
7 年前