文章目录
Requirements
Python (3.5, 3.6, 3.7, 3.8, 3.9)
Django (2.2, 3.0, 3.1)
下载及配置
下载:
pip install djangorestframework
配置:
在INSTALLED_APPS中添加 ‘rest_framework’ 项。
INSTALLED_APPS = [
...
'rest_framework',
]
REST framework API的所有全局设定都会放在一个叫REST_FRAMEWORK的配置词典里。首先把下面的内容添加到你的settings.py模块中:
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'
]
}
请求对象(Request objects)
request.data
处理任意数据 适用于’POST’,'PUT’和’PATCH’方法。它支持REST framework灵活的请求解析,而不仅仅支持表单数据。 例如,你可以以与处理传入表单数据相同的方式处理传入的JSON数据。request.query_params
是request.GET的一个更准确的同义词。request.user
通常返回一个 django.contrib.auth.models.User 实例, 尽管该行为取决于所使用的的认证策略。
如果请求未认证则 request.user 的默认值为django.contrib.auth.models.AnonymousUser的一个实例。request.auth
返回任何其他身份验证上下文。
request.auth 的确切行为取决于所使用的的认证策略,但它通常可以是请求被认证的token的实例。
如果请求未认证或者没有其他上下文,则 request.auth 的默认值为 None.request.method
返回请求的HTTP方法的 大写 字符串表示形式。
透明地支持基于浏览器的 PUT, PATCH 和 DELETE 表单。request.content_type
返回表示HTTP请求正文的媒体类型的字符串对象,如果未提供媒体类型,则返回空字符串。request.stream
返回一个表示请求主体内容的流。request.META
request.session
状态码(Status codes)
在你的视图(views)中使用纯数字的HTTP 状态码并不总是那么容易被理解。而且如果错误代码出错,很容易被忽略。REST框架为status模块中的每个状态代码(如HTTP_400_BAD_REQUEST)提供更明确的标识符。
包装(wrapping)API视图
REST框架提供了两个可用于编写API视图的包装器(wrappers)。
- 用于基于函数视图的@api_view装饰器。
- 用于基于类视图的APIView类。
1. 基于函数的视图
@api_view(http_method_names=['GET'], exclude_from_schema=False)
此功能的核心是api_view装饰器,它接受视图应该响应的HTTP方法列表的参数。
默认的情况下,只有GET请求会被接受
from rest_framework.decorators import api_view
@api_view()
def hello_world(request):
return Response({"message": "Hello, world!"})
@api_view(['GET', 'POST'])
def hello_world(request):
if request.method == 'POST':
return Response({"message": "Got some data!", "data": request.data})
return Response({"message": "Hello, world!"})
API 策略装饰器
REST framework提供了一组可以加到视图上的装饰器来重写默认设置。这些装饰器必须放在@api_view的后(下)面。比如,要创建一个使用限制器确保特定用户每天只能调用一次的视图,可以用@throttle_classes装饰器并给它传递一个限制器类的列表。
from rest_framework.decorators import api_view, throttle_classes
from rest_framework.throttling import UserRateThrottle
class OncePerDayUserThrottle(UserRateThrottle):
rate = '1/day'
@api_view(['GET'])
@throttle_classes([OncePerDayUserThrottle])
def view(request):
return Response({"message": "Hello for today! See you tomorrow!"})
可用的装饰器有:
@renderer_classes(...)
@parser_classes(...)
@authentication_classes(...)
@throttle_classes(...)
@permission_classes(...)
这些装饰器中的每一个都接受一个参数,这个参数必须是类的列表或元组。
2、基于类的视图
REST framework提供了一个APIView类,它是Django的View类的子类。
2.1 View与APIView的区别
APIView类和一般的View类有以下不同:
- 被传入到处理方法的请求不会是Django的HttpRequest类的实例,而是REST framework的Request类的实例。
- 处理方法可以返回REST
framework的Response,而不是Django的HttpRequest。视图会管理内容协议,给响应设置正确的渲染器。 - 任何APIException异常都会被捕获,并且传递给合适的响应。
- 进入的请求将会经过认证,合适的权限和(或)节流检查会在请求被派发到处理方法之前运行。
2.2 实现
在URL传递过程,我们只需要调用APIView的as_view()方法,然后URL就会调用业务类对应的HTTP方法,如get,post,put,delete(对应查 增 改 删)方法。
1.使用django自带的view,获取一个Card表里面的卡号信息:
# models.py
class Card(models.Model):
card_id = models.CharField(max_length=30, verbose_name="卡号", default="")
card_user = models.CharField(max_length=10, verbose_name="姓名", default="")
add_time = models.DateField(auto_now=True, verbose_name="添加时间")
class Meta:
verbose_name_plural = '银行卡账户'
verbose_name = "银行卡账户_基本信息"
def __str__(self):
return self.card_id
# views.py
from django.http import JsonResponse
from rest_framework import serializers
from django.core import serializers as dj_serializers # 避免和rest_framework里面的serializers冲突
from .models import *
from django.views.generic.base import View
import json
class CardListView(View):
'''基于django的view实现获取card列表'''
def get(self, request):
data = {}
cards = Card.objects.all()
data['result'] = json.loads(dj_serializers.serialize("json", cards))
return JsonResponse(data)
2.使用REST framework的APIView
REST framework的APIView继承了django的View类,先序列化Card类,这里的序列化用rest_framework里面的ModelSerializer。
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import serializers
from .models import *
from rest_framework.permissions import IsAuthenticated,AllowAny
from rest_framework.authentication import TokenAuthentication
class CardAPISerializer(serializers.ModelSerializer): # 继承自ModelSerializer类
'''序列化数据的类,根据model表来获取字段'''
class Meta:
model = Card
fields = '__all__'
class CardListAPIView(APIView):
'''REST framework的APIView实现获取card列表 '''
# authentication_classes = (TokenAuthentication,) # token认证
# permission_classes = (IsAuthenticated,) # IsAuthenticated 仅通过认证的用户
permission_classes = (AllowAny,) # 允许所有用户
def get(self, request, format=None):
"""
Return a list of all users.
"""
cards = Card.objects.all()
serializer = CardAPISerializer(cards, many=True)
return Response(serializer.data)
# urls.py
from apiapp import views
from django.conf.urls import url
urlpatterns = [
url(r'^api/v1/cardlist/$', views.CardListAPIView.as_view()),
]