import datetime
import dateutil.parser
import logging
from decimal import Decimal
from django.core.cache import cache
from django.core.exceptions import ObjectDoesNotExist
from django.db.models.fields.related import ForeignKey, OneToOneField
from rest_framework import exceptions
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status
from mongoengine.errors import DoesNotExist
from rest_framework_simplify.exceptions import ParseException
from rest_framework_simplify.mapper import Mapper
from rest_framework_simplify.serializer import MongoEngineSerializer, SQLEngineSerializer
from rest_framework_simplify.services.sql_executor.service import SQLExecutorService
from rest_framework_simplify.errors import ErrorMessages
class SimplifyView(APIView):
def __init__(self, model, linked_objects=[], supported_methods=[], read_db='default', write_db='default'):
self.read_db = read_db
self.write_db = write_db
self.model = model
self.supported_methods = supported_methods
self.linked_objects = linked_objects
if self.get_db_engine() == 'mongo':
self.DoesNotExist = DoesNotExist
else:
self.DoesNotExist = ObjectDoesNotExist
if self.get_db_engine() == 'mongo':
self.serializer = MongoEngineSerializer
else:
self.serializer = SQLEngineSerializer
def get_db_engine(self):
if hasattr(self.model, 'validate'):
return 'mongo'
else:
return 'sql'
def delete(self, request, pk=None, parent_resource=None, parent_pk=None):
if parent_pk and parent_resource and self.linked_objects:
if 'DELETE_SUB' not in self.supported_methods:
return self.create_response(error_message=ErrorMessages.DELETE_SUB_NOT_SUPPORTED
.format(self.model.__name__))
else:
if 'DELETE' not in self.supported_methods:
return self.create_response(error_message=ErrorMessages.DELETE_NOT_SUPPORTED.format(self.model.__name__))
try:
obj = self.model.objects.using(self.read_db).get(pk=pk)
except self.DoesNotExist:
raise self.DoesNotExist(ErrorMessages.DOES_NOT_EXIST.format(self.model.__name__, pk))
# check query param to only delete linker
delete_link_only = request.query_params.get('deleteLinkOnly', False)
# further checks
for linked_object in self.linked_objects:
# we have a linking table we need to clear the linking table objects
if linked_object['sub_resource_name'] and linked_object['linking_cls']:
kwargs = {
linked_object['sub_resource_name']: obj
}
# get the linking table items
linked_objs = linked_object['linking_cls'].objects.using(self.read_db).filter(**kwargs)
for linked_obj in linked_objs:
linked_obj.delete(using=self.read_db)
else:
pass
if not delete_link_only:
obj.delete(using=self.write_db)
return self.create_response()
def get(self, request, pk=None, parent_resource=None, parent_pk=None):
meta_request = request.query_params.get('meta', False)
if meta_request:
# grab models fields and return them as a dict
meta_data = self.model.get_meta_data()
return self.create_response(body=meta_data)
# handle caching
cache_key = None
if hasattr(self.model, 'CACHE'):
cache_key = request.get_full_path()
result = cache.get(cache_key, None)
if result:
return self.create_response(body=result, using_cache=True, cache_key=cache_key)
obj = None
# if we have a primary key we are returning one result
if pk:
if 'GET' not in self.supported_methods:
return self.create_response(error_message=ErrorMessages.GET_NOT_SUPPORTED.format(self.model.__name__))
# try to get the obj from db
try:
obj = self.model.objects.using(self.read_db).get(pk=pk)
except self.DoesNotExist:
raise self.DoesNotExist(ErrorMessages.DOES_NOT_EXIST.format(self.model.__name__, pk))
else:
# we could be a sub resource so we need to check if a parent_resource was passed in
if parent_pk and parent_resource and self.linked_objects:
snake_cased_url_tail = Mapper.camelcase_to_underscore(request.get_full_path().split('/')[-1])
lives_on_parent_results = [i for i in self.linked_objects if 'lives_on_parent' in i
and i['lives_on_parent'] and i['sub_resource_name'] == snake_cased_url_tail]
if len(lives_on_parent_results) > 0:
if 'GET_SUB' not in self.supported_methods:
return self.create_response(error_message=ErrorMessages.GET_SUB_NOT_SUPPORTED.format(self.model.__name__))
linked_object = lives_on_parent_results[0]
parent_obj = linked_object['parent_cls'].objects.using(self.read_db).get(pk=parent_pk)
obj = getattr(parent_obj, linked_object['sub_resource_name'])
else:
# check if this method has authorized sub resources
if 'GET_LIST_SUB' not in self.supported_methods:
return self.create_response(error_message=ErrorMessages.GET_LIST_SUB_NOT_SUPPORTED.format(self.model.__name__))
# find the resource that this request is looking for
for linked_object in self.linked_objects:
if linked_object['parent_resource'] == parent_resource:
if linked_object['parent_cls']:
# get the resource
parent_obj = linked_object['parent_cls'].objects.using(self.read_db).get(pk=parent_pk)
else:
parent_obj = parent_pk
# setup kwargs for django's orm to query
kwargs = {
linked_object['parent_name']: parent_obj
}
# if there is a linking table do that logic
if linked_object['linking_cls']:
# get the linking table items
linked_objs = linked_object['linking_cls'].objects.using(self.read_db).filter(**kwargs)
# go through linking table items and get the sub resources from each entry into a list
linked_obj_ids = [getattr(linked_obj, linked_object['sub_resource_name']).id for linked_obj in
linked_objs]
obj = self.model.objects.using(self.read_db).filter(pk__in=linked_obj_ids)
# no linking table and the link is on this obj itself
else:
obj = self.model.objects.using(self.read_db).filter(**kwargs)
else:
# trying to get ALL items in DB
if 'GET_LIST' not in self.supported_methods:
return self.create_response(error_message=ErrorMessages.GET_LIST_NOT_SUPPORTED.format(self.model.__name__))
obj = self.model.objects.using(self.read_db).all()
# handle includes
req_includes = request.query_params.get('include', [])
if req_includes:
req_includes = req_includes.split(',')
if type(req_includes) is not list:
req_includes = [req_includes]
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
共19个文件
py:18个
pkg-info:1个
资源分类:Python库 所属语言:Python 资源全名:django-rest-framework-simplify-1.1.1.dev.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
资源推荐
资源详情
资源评论
收起资源包目录
django-rest-framework-simplify-1.1.1.dev.tar.gz (19个子文件)
django-rest-framework-simplify-1.1.1.dev
PKG-INFO 298B
rest_framework_simplify
models.py 13KB
apps.py 121B
signature.py 751B
mapper.py 6KB
errors.py 2KB
helpers.py 1KB
__init__.py 0B
fields.py 3KB
views.py 28KB
serializer.py 16KB
services
__init__.py 0B
sql_executor
service.py 7KB
__init__.py 0B
tests.py 3KB
exceptions.py 127B
exceptions.py 538B
forms.py 8KB
setup.py 423B
共 19 条
- 1
资源评论
挣扎的蓝藻
- 粉丝: 12w+
- 资源: 15万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于Python的歌曲搜索播放器源代码,利用requests库对歌曲宝网站进行歌曲采集,并用tkinter做了UI
- kernel-devel-3.10.0-1062.21.1.el7.x86-64.rpm
- kernel-3.10.0-1062.21.1.el7.x86-64.rpm
- A2_smvs.zip
- Assignment2(4).ipynb
- 用pytorch框架实现的油井时间序列动态预测的模型,其中包含一些传统的时间序列预测方法 .zip
- TimesNet作为一般时间序列分析强大的基础模型 在长短期预测、插补、异常检测和分类5个主流任务上取得了一致的前沿成果.zip
- 实现结构体序列化和反序列化工具类CSearchive,支持基本类型,C++STL容器以及对象 .zip
- 时间序列遥感变化检测.zip
- 时间序列数据集收集以及数据分析.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功