一切皆是资源,操作只是请求方式。
url里面不能出现任何一个动词
https://www.cnblogs.com/yuanchenqi/articles/8719520.html
pip install djangorestframework
使用
先到app中注册
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog.apps.BlogConfig',
'rest_framework',
]
views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer
from django.shortcuts import HttpResponse
from rest_framework.versioning import QueryParameterVersioning, URLPathVersioning
# Create your views here.
class CourseView(APIView):
renderer_classes = [JSONRenderer, BrowsableAPIRenderer]
def get(self, request, *args, **kwargs):
# self.dispatch
print(request.version)
return Response('....')
# return HttpResponse('ok')
setting
版本
# restframework Version
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': ['rest_framework.renderers.JSONRenderer', 'rest_framework.renderers.BrowsableAPIRenderer'],
# 版本问题
# 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.QueryParameterVersioning',
# 'ALLOWED_VERSIONS': ['v1', 'v2'], # 允许的斑斑
# 'VERSION_PARAM': 'version', # 参数
# 'DEFAULT_VERSION': 'v1', # 默认版本
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
}
urlpatterns = [
# re_path(r'^(?P[v1|v2]+)/course/$', views.CourseView.as_view()),
path('course/', views.CourseView.as_view()),
]
在mounted方法中发ajax请求后端api拿数据(axios) npm install axios --save
解决跨域问题
axios XHR network error
加响应头
from django.utils.deprecation import MiddlewareMixin
class CORSMiddleWare(MiddlewareMixin):
def process_response(self, request, response): # 必须定义这个名字的方法,两个参数也是必须写的
# 添加响应头解决跨域问题
# 允许你的域名来获取我的数据
# response['Access-Control-Allow-Origin'] = "http://127.0.0.1:8080"
# 允许所有
response['Access-Control-Allow-Origin'] = "*"
# 允许你携带Content-Type请求头, 不能写* 可以 , 加
response['Access-Control-Allow-Headers'] = "Content-Type"
# 允许你发送DELETE,PUT请求
response['Access-Control-Allow-Methods'] = "DELETE,PUT"
return response
继承了Django的View
APIView下的dispatch()构建了一个新的request
request.data POSTde 数据都可以拿到
request.GET 拿到get的数据
from api import models
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.viewsets import ViewSetMixin
from rest_framework import serializers
from rest_framework.pagination import PageNumberPagination
class ArticleSerializers(serializers.ModelSerializer):
# 自定义字段处理的onetoone/fk/choice
category = serializers.CharField(source='category.name')
# manytomany
author = serializers.SerializerMethodField()
tag = serializers.SerializerMethodField()
class Meta:
model = models.Article
fields = ['title', 'author', 'content', 'desc', 'cover', 'add_time', 'upup', 'downdown', 'click_count',
'category', 'update_time', 'tag']
# SerializerMethodField要定义get方法
def get_tag(self, obj):
# 获取所有的文章标签
queryset = obj.tag.all()
return [{
'id':row.id, 'name':row.name, 'article_num':row.get_items()} for row in queryset]
def get_author(self, obj):
# 获取所有的文章标签
queryset = obj.author.all()
return [{
'id':row.id, 'name':row.username} for row in queryset]
class PNPagination(PageNumberPagination):
page_size = 2
page_query_param = 'page'
page_size_query_param = "size"
max_page_size = 5
# 要重写as_view方法必须继承ViewSetMixin
class ArticleView(ViewSetMixin, APIView):
def list(self, request, *args, **kwargs):
""":arg
文章列表接口
"""
# 分页器
page = PNPagination()
ret = {
'code': 200, 'data':None}
try:
queryset = models.Article.objects.all()
page_list = page.paginate_queryset(queryset, request, self)
ser = ArticleSerializers(instance=page_list, many=True) # 如果单个序列化对象则many=False
ret['data'] = ser.data
except Exception as e:
ret['code'] = '500'
ret['error'] = '获取文章信息失败!'
return Response(ret)
def retrieve(self, request, *args, **kwargs):
""":arg课程详细接口"""
ret = {
'code': 200, 'data': None}
try:
pk = kwargs.get('pk')
obj = models.Article.objects.filter(id=pk).first()
ser = ArticleSerializers(instance=obj, many=False) # 如果单个序列化对象则many=False
ret['data'] = ser.data
except Exception as e:
ret['code'] = '500'
ret['error'] = '获取文章详细信息失败!'
return Response(ret)
如果定制了多对多显示方法,还要进行bs.validate()下的bs.save()的话,则需要重写create方法
超链接字段
序列化时要加 context{“request”: request}
as_view传参 字典,指定get等方法用什么方法去处理
{
'get':'list', 'put':'update', 'delete':'destroy', 'post':'create'}
{
'get':'retrieve', 'put':'update', 'delete':'destroy', 'post':'create'}
# 评论
path('comment/', comment.CommentView.as_view({
'get': 'list', 'post': 'create'})),
re_path(r'^comment/(?P\d+)/$' , comment.CommentView.as_view({
'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
# view
from rest_framework.viewsets import ModelViewSet
from api import models
from rest_framework import serializers
from rest_framework.pagination import PageNumberPagination
class CommentModelSerializers(serializers.ModelSerializer):
class Meta:
model = models.Comment
fields = "__all__"
# 自定义字段需要重写save方法
# 自定义错误信息等
# 分页
class PNPagination(PageNumberPagination):
page_size = 2
page_query_param = 'page'
page_size_query_param = "size"
max_page_size = 5
class CommentView(ModelViewSet):
queryset = models.Comment.objects.all()
serializer_class = CommentModelSerializers
pagination_class = PNPagination
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from api import models
class UserAuth(BaseAuthentication):
def authenticate(self, request):
ret = {
'code': 200}
token = request.query_params.get('token')
obj = models.UserToken.objects.filter(token=token).first()
if obj:
return obj.username.username, obj
else:
ret = {
'code':500, 'error': 'token值不正确!'}
raise AuthenticationFailed(ret)
class CommentView(ModelViewSet):
queryset = models.Comment.objects.all()
serializer_class = CommentModelSerializers
pagination_class = PNPagination
# authentication_classes = [UserAuth, ]
REST_FRAMEWORK = {
# 全局认证
# "DEFAULT_AUTHENTICATION_CLASSES":["api.utils.userauth.UserAuth",]
}
class UserPermission(object):
message = '只有管理员才可以访问!'
def has_permission(self, request, view):
username = request.user
user_obj = models.UserInfo.objects.filter(username=username).first()
print(user_obj)
if user_obj and user_obj.is_superuser:
print(user_obj.is_superuser)
return True
else:
return False
class CommentView(ModelViewSet):
queryset = models.Comment.objects.all()
serializer_class = CommentModelSerializers
pagination_class = PNPagination
authentication_classes = [UserAuth, ]
permission_classes = [UserPermission, ]
Responce:浏览器响应的一种方式。