操作日志后端逻辑完成
parent
4cfdde7622
commit
38e09f556b
|
@ -59,7 +59,7 @@ MIDDLEWARE = [
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
# 'vadmin.op_drf.middleware.ApiLoggingMiddleware', # 用于记录API访问日志
|
'vadmin.op_drf.middleware.ApiLoggingMiddleware', # 用于记录API访问日志
|
||||||
]
|
]
|
||||||
# 允许跨域源
|
# 允许跨域源
|
||||||
CORS_ORIGIN_ALLOW_ALL = CORS_ORIGIN_ALLOW_ALL
|
CORS_ORIGIN_ALLOW_ALL = CORS_ORIGIN_ALLOW_ALL
|
||||||
|
@ -313,3 +313,7 @@ CAPTCHA_NOISE_FUNCTIONS = (
|
||||||
)
|
)
|
||||||
# CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.random_char_challenge'
|
# CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.random_char_challenge'
|
||||||
CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.math_challenge'
|
CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.math_challenge'
|
||||||
|
|
||||||
|
API_LOG_ENABLE = True
|
||||||
|
# API_LOG_METHODS = 'ALL' # ['POST', 'DELETE']
|
||||||
|
API_LOG_METHODS = ['POST', 'DELETE'] # ['POST', 'DELETE']
|
||||||
|
|
|
@ -16,11 +16,27 @@ class ViewLogger(object):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.view = view
|
self.view = view
|
||||||
self.request = request
|
self.request = request
|
||||||
|
self.model = None
|
||||||
self.log_prefix: str = ''
|
self.log_prefix: str = ''
|
||||||
|
if self.view and hasattr(self.view.get_queryset(), 'model'):
|
||||||
|
self.model: Model = self.view.get_queryset().model
|
||||||
|
elif self.view and hasattr(self.view.get_serializer(), 'Meta') and hasattr(self.view.get_serializer().Meta,
|
||||||
|
'model'):
|
||||||
|
self.model: Model = self.view.get_serializer().Meta.model
|
||||||
|
if self.model:
|
||||||
|
request.session['model_name'] = getattr(self.model, '_meta').verbose_name
|
||||||
|
|
||||||
def handle(self, request: Request, *args, **kwargs):
|
def handle(self, request: Request, *args, **kwargs):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def logger(self, msg):
|
||||||
|
"""
|
||||||
|
|
||||||
|
:param msg:
|
||||||
|
:return: logger
|
||||||
|
"""
|
||||||
|
self.request.session['request_msg'] = msg
|
||||||
|
return logger
|
||||||
|
|
||||||
class APIViewLogger(ViewLogger):
|
class APIViewLogger(ViewLogger):
|
||||||
"""
|
"""
|
||||||
|
@ -36,7 +52,7 @@ class APIViewLogger(ViewLogger):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, view=None, request=None, *args, **kwargs) -> None:
|
def __init__(self, view=None, request=None, *args, **kwargs) -> None:
|
||||||
super().__init__()
|
super().__init__(view, request, *args, **kwargs)
|
||||||
self.view: APIView = view
|
self.view: APIView = view
|
||||||
self.request: Request = request
|
self.request: Request = request
|
||||||
self.user = request.user
|
self.user = request.user
|
||||||
|
@ -52,12 +68,7 @@ class ModelViewLogger(APIViewLogger):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, view=None, request=None, *args, **kwargs) -> None:
|
def __init__(self, view=None, request=None, *args, **kwargs) -> None:
|
||||||
super().__init__(view, request)
|
super().__init__(view, request, *args, **kwargs)
|
||||||
|
|
||||||
if hasattr(self.view.get_queryset(), 'model'):
|
|
||||||
self.model: Model = self.view.get_queryset().model
|
|
||||||
elif hasattr(self.view.get_serializer(), 'Meta') and hasattr(self.view.get_serializer().Meta, 'model'):
|
|
||||||
self.model: Model = self.view.get_serializer().Meta.model
|
|
||||||
|
|
||||||
|
|
||||||
class RelationshipViewLogger(APIViewLogger):
|
class RelationshipViewLogger(APIViewLogger):
|
||||||
|
@ -103,7 +114,7 @@ class CustomerRelationshipViewLogger(RelationshipViewLogger):
|
||||||
model_name = getattr(self.view.model, '_meta').verbose_name
|
model_name = getattr(self.view.model, '_meta').verbose_name
|
||||||
to_field_name = self.view.to_field_name
|
to_field_name = self.view.to_field_name
|
||||||
to_model_name = getattr(self.view.relationship_model, '_meta').verbose_name
|
to_model_name = getattr(self.view.relationship_model, '_meta').verbose_name
|
||||||
logger.info(
|
self.logger(
|
||||||
f'{self.log_prefix}用户[username={operator}]新增, {model_name}实例[{to_field_name}={self.instanceId}]与{to_model_name}的关联关系')
|
f'{self.log_prefix}用户[username={operator}]新增, {model_name}实例[{to_field_name}={self.instanceId}]与{to_model_name}的关联关系')
|
||||||
|
|
||||||
def handle_put(self, request: Request, *args, **kwargs):
|
def handle_put(self, request: Request, *args, **kwargs):
|
||||||
|
@ -114,7 +125,7 @@ class CustomerRelationshipViewLogger(RelationshipViewLogger):
|
||||||
model_name = getattr(self.view.model, '_meta').verbose_name
|
model_name = getattr(self.view.model, '_meta').verbose_name
|
||||||
to_field_name = self.view.to_field_name
|
to_field_name = self.view.to_field_name
|
||||||
to_model_name = getattr(self.view.relationship_model, '_meta').verbose_name
|
to_model_name = getattr(self.view.relationship_model, '_meta').verbose_name
|
||||||
logger.info(
|
self.logger(
|
||||||
f'{self.log_prefix}用户[username={operator}]重置, {model_name}实例[{to_field_name}={self.instanceId}]与{to_model_name}的关联关系')
|
f'{self.log_prefix}用户[username={operator}]重置, {model_name}实例[{to_field_name}={self.instanceId}]与{to_model_name}的关联关系')
|
||||||
|
|
||||||
def handle_delete(self, request: Request, *args, **kwargs):
|
def handle_delete(self, request: Request, *args, **kwargs):
|
||||||
|
@ -125,7 +136,7 @@ class CustomerRelationshipViewLogger(RelationshipViewLogger):
|
||||||
model_name = getattr(self.view.model, '_meta').verbose_name
|
model_name = getattr(self.view.model, '_meta').verbose_name
|
||||||
to_field_name = self.view.to_field_name
|
to_field_name = self.view.to_field_name
|
||||||
to_model_name = getattr(self.view.relationship_model, '_meta').verbose_name
|
to_model_name = getattr(self.view.relationship_model, '_meta').verbose_name
|
||||||
logger.info(
|
self.logger(
|
||||||
f'{self.log_prefix}用户[username={operator}]移除, {model_name}实例[{to_field_name}={self.instanceId}]与{to_model_name}的关联关系')
|
f'{self.log_prefix}用户[username={operator}]移除, {model_name}实例[{to_field_name}={self.instanceId}]与{to_model_name}的关联关系')
|
||||||
|
|
||||||
|
|
||||||
|
@ -144,7 +155,7 @@ class CustomerModelViewLogger(ModelViewLogger):
|
||||||
pass
|
pass
|
||||||
operator = self.user.username
|
operator = self.user.username
|
||||||
model_name = getattr(self.model, '_meta').verbose_name
|
model_name = getattr(self.model, '_meta').verbose_name
|
||||||
logger.info(f'{self.log_prefix}用户[username={operator}]检索{model_name}:[{instance}]')
|
self.logger(f'{self.log_prefix}用户[username={operator}]检索{model_name}:[{instance}]')
|
||||||
|
|
||||||
def handle_list(self, request: Request, *args, **kwargs):
|
def handle_list(self, request: Request, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
@ -153,7 +164,7 @@ class CustomerModelViewLogger(ModelViewLogger):
|
||||||
pass
|
pass
|
||||||
operator = self.user.username
|
operator = self.user.username
|
||||||
model_name = getattr(self.model, '_meta').verbose_name
|
model_name = getattr(self.model, '_meta').verbose_name
|
||||||
logger.info(f'{self.log_prefix}用户[username={operator}]查询{model_name}')
|
self.logger(f'{self.log_prefix}用户[username={operator}]查询{model_name}')
|
||||||
|
|
||||||
def handle_create(self, request: Request, instance: Model = None, *args, **kwargs):
|
def handle_create(self, request: Request, instance: Model = None, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
@ -162,7 +173,7 @@ class CustomerModelViewLogger(ModelViewLogger):
|
||||||
pass
|
pass
|
||||||
operator = self.user.username
|
operator = self.user.username
|
||||||
model_name = getattr(self.model, '_meta').verbose_name
|
model_name = getattr(self.model, '_meta').verbose_name
|
||||||
logger.info(f'{self.log_prefix}用户[username={operator}]创建{model_name}:[{instance}]')
|
self.logger(f'{self.log_prefix}用户[username={operator}]创建{model_name}:[{instance}]')
|
||||||
|
|
||||||
def handle_update(self, request: Request, instance: Model = None, *args, **kwargs):
|
def handle_update(self, request: Request, instance: Model = None, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
@ -171,7 +182,7 @@ class CustomerModelViewLogger(ModelViewLogger):
|
||||||
pass
|
pass
|
||||||
operator = self.user.username
|
operator = self.user.username
|
||||||
model_name = getattr(self.model, '_meta').verbose_name
|
model_name = getattr(self.model, '_meta').verbose_name
|
||||||
logger.info(f'{self.log_prefix}用户[username={operator}]更新{model_name}:[{instance}]')
|
self.logger(f'{self.log_prefix}用户[username={operator}]更新{model_name}:[{instance}]')
|
||||||
|
|
||||||
def handle_partial_update(self, request: Request, instance: Model = None, *args, **kwargs):
|
def handle_partial_update(self, request: Request, instance: Model = None, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
@ -180,7 +191,7 @@ class CustomerModelViewLogger(ModelViewLogger):
|
||||||
pass
|
pass
|
||||||
operator = self.user.username
|
operator = self.user.username
|
||||||
model_name = getattr(self.model, '_meta').verbose_name
|
model_name = getattr(self.model, '_meta').verbose_name
|
||||||
logger.info(f'{self.log_prefix}用户[username={operator}]部分更新{model_name}:[{instance}]')
|
self.logger(f'{self.log_prefix}用户[username={operator}]部分更新{model_name}:[{instance}]')
|
||||||
|
|
||||||
def handle_destroy(self, request: Request, instance: Model = None, *args, **kwargs):
|
def handle_destroy(self, request: Request, instance: Model = None, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
@ -189,4 +200,4 @@ class CustomerModelViewLogger(ModelViewLogger):
|
||||||
pass
|
pass
|
||||||
operator = self.user.username
|
operator = self.user.username
|
||||||
model_name = getattr(self.model, '_meta').verbose_name
|
model_name = getattr(self.model, '_meta').verbose_name
|
||||||
logger.info(f'{self.log_prefix}用户[username={operator}]删除{model_name}:[{instance}]')
|
self.logger(f'{self.log_prefix}用户[username={operator}]删除{model_name}:[{instance}]')
|
||||||
|
|
|
@ -2,70 +2,31 @@
|
||||||
django中间件
|
django中间件
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import json
|
|
||||||
import datetime
|
|
||||||
from django.utils.deprecation import MiddlewareMixin
|
|
||||||
from mongoengine import DynamicDocument, StringField, IntField, DictField, DateTimeField
|
|
||||||
from rest_framework_mongoengine.serializers import DocumentSerializer
|
|
||||||
import logging
|
|
||||||
from ..utils.decorators import exceptionHandler
|
|
||||||
from ..utils.request_util import get_request_ip, get_request_data, get_request_path
|
|
||||||
from .viewsets import CustomMongoModelViewSet
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
logger = logging.getLogger(__name__)
|
from django.utils.deprecation import MiddlewareMixin
|
||||||
|
|
||||||
|
from apps.vadmin.system.models import RequestLog
|
||||||
class ApiLog(DynamicDocument):
|
from ..utils.request_util import get_request_ip, get_request_data, get_request_path, get_browser, get_os, \
|
||||||
"""
|
get_login_location
|
||||||
API访问日志的Mongo模型
|
|
||||||
"""
|
|
||||||
request_ip = StringField(verbose_name="request_ip", help_text="请求IP")
|
|
||||||
request_username = StringField(verbose_name="request_username", help_text="请求username")
|
|
||||||
request_method = StringField(verbose_name="request_method", help_text="请求方法")
|
|
||||||
request_path = StringField(verbose_name="request_path", help_text="请求路径")
|
|
||||||
request_body = DictField(verbose_name="request_body", help_text="请求参数")
|
|
||||||
response_code = IntField(verbose_name="response_code", help_text="响应状态码")
|
|
||||||
response_reason = StringField(verbose_name="response_reason", help_text="响应简述")
|
|
||||||
access_time = DateTimeField(verbose_name="access_time", help_text="访问时间")
|
|
||||||
|
|
||||||
|
|
||||||
class ApiLogSerializer(DocumentSerializer):
|
|
||||||
"""
|
|
||||||
API访问日志的Mongo序列化器
|
|
||||||
"""
|
|
||||||
class Meta:
|
|
||||||
model = ApiLog
|
|
||||||
fields = '__all__'
|
|
||||||
|
|
||||||
|
|
||||||
class ApiLogModelViewSet(CustomMongoModelViewSet):
|
|
||||||
"""
|
|
||||||
API访问日志的CRUD视图
|
|
||||||
"""
|
|
||||||
queryset = ApiLog.objects.all()
|
|
||||||
serializer_class = ApiLogSerializer
|
|
||||||
search_fields = ('request_ip', 'request_username', 'request_method', 'response_reason', 'source_system')
|
|
||||||
ordering = '-access_time' # 默认排序
|
|
||||||
|
|
||||||
|
|
||||||
class ApiLoggingMiddleware(MiddlewareMixin):
|
class ApiLoggingMiddleware(MiddlewareMixin):
|
||||||
"""
|
"""
|
||||||
用于记录API访问日志中间件
|
用于记录API访问日志中间件
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, get_response=None):
|
def __init__(self, get_response=None):
|
||||||
super().__init__(get_response)
|
super().__init__(get_response)
|
||||||
self.enable = op_settings.get_api_log_setting().get('enable', False)
|
self.enable = settings.API_LOG_ENABLE or False
|
||||||
self.methods = op_settings.get_api_log_setting().get('methods', set())
|
self.methods = settings.API_LOG_METHODS or set()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@exceptionHandler()
|
|
||||||
def __handle_request(cls, request):
|
def __handle_request(cls, request):
|
||||||
request.request_ip = get_request_ip(request)
|
request.request_ip = get_request_ip(request)
|
||||||
request.request_data = get_request_data(request)
|
request.request_data = get_request_data(request)
|
||||||
request.access_time = datetime.datetime.now()
|
request.request_path = get_request_path(request)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@exceptionHandler(logger=logger)
|
|
||||||
def __handle_response(cls, request, response):
|
def __handle_response(cls, request, response):
|
||||||
# request_data,request_ip由PermissionInterfaceMiddleware中间件中添加的属性
|
# request_data,request_ip由PermissionInterfaceMiddleware中间件中添加的属性
|
||||||
body = getattr(request, 'request_data', {})
|
body = getattr(request, 'request_data', {})
|
||||||
|
@ -74,16 +35,20 @@ class ApiLoggingMiddleware(MiddlewareMixin):
|
||||||
body['password'] = '*' * len(body['password'])
|
body['password'] = '*' * len(body['password'])
|
||||||
info = {
|
info = {
|
||||||
'request_ip': getattr(request, 'request_ip', 'unknown'),
|
'request_ip': getattr(request, 'request_ip', 'unknown'),
|
||||||
'request_username': request.user.username,
|
'creator': request.user,
|
||||||
'request_method': request.method,
|
'request_method': request.method,
|
||||||
'request_path': request.path,
|
'request_path': request.request_path,
|
||||||
'request_body': body,
|
'request_body': body,
|
||||||
'response_code': response.status_code,
|
'response_code': response.status_code,
|
||||||
'response_reason': response.reason_phrase,
|
'request_location': get_login_location(request),
|
||||||
'source_system': getattr(settings,'SOURCE_SYSTEM_NAME',None),
|
'request_os': get_os(request),
|
||||||
'access_time': request.access_time.strftime('%Y-%m-%d %H:%M:%S'),
|
'request_browser': get_browser(request),
|
||||||
|
'request_msg': request.session.get('request_msg'),
|
||||||
|
'status': True if response.data.get('code') in [200, 204] else False,
|
||||||
|
'json_result': {"code": response.data.get('code'), "msg": response.data.get('msg')},
|
||||||
|
'request_modular': request.session.get('model_name'),
|
||||||
}
|
}
|
||||||
log = ApiLog(**info)
|
log = RequestLog(**info)
|
||||||
log.save()
|
log.save()
|
||||||
|
|
||||||
def process_request(self, request):
|
def process_request(self, request):
|
||||||
|
|
|
@ -99,189 +99,3 @@ class CustomAPIView(APIView):
|
||||||
self.permission_denied(
|
self.permission_denied(
|
||||||
request, message=getattr(permission, 'message', None)
|
request, message=getattr(permission, 'message', None)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class BatchModelApIView(CustomAPIView):
|
|
||||||
"""
|
|
||||||
模型批量CRUD通用视图
|
|
||||||
"""
|
|
||||||
model = None
|
|
||||||
serializer_class = None
|
|
||||||
POST_serializer_class = None
|
|
||||||
PUT_serializer_class = None
|
|
||||||
field_name = 'instanceId'
|
|
||||||
instanceId_list_param_name = 'instanceIdList'
|
|
||||||
instance_info_param_name = 'info'
|
|
||||||
|
|
||||||
def get_serializer(self, *args, **kwargs):
|
|
||||||
if not self.request:
|
|
||||||
return None
|
|
||||||
serializer_class = getattr(self, f"{self.request.method}_serializer_class", None) or getattr(self,
|
|
||||||
'serializer_class')
|
|
||||||
serializer = serializer_class(*args, **kwargs)
|
|
||||||
if isinstance(serializer, CustomModelSerializer):
|
|
||||||
serializer.request = self.request
|
|
||||||
return serializer
|
|
||||||
|
|
||||||
def get(self, request: Request = None, *args, **kwargs):
|
|
||||||
data = self.get_serializer(self.model.objects.filter(**{f'{self.field_name}__in': request.data}),
|
|
||||||
many=True).data
|
|
||||||
return SuccessResponse(data=data)
|
|
||||||
|
|
||||||
def post(self, request: Request = None, *args, **kwargs):
|
|
||||||
data = []
|
|
||||||
for info in request.data:
|
|
||||||
serializer = self.get_serializer(data=info)
|
|
||||||
serializer.is_valid(raise_exception=True)
|
|
||||||
serializer.save()
|
|
||||||
data.append(serializer.data)
|
|
||||||
return SuccessResponse(data=data)
|
|
||||||
|
|
||||||
def put(self, request: Request = None, *args, **kwargs):
|
|
||||||
data = []
|
|
||||||
instanceId_list = request.data.get(self.instanceId_list_param_name, [])
|
|
||||||
info = request.data.get(self.instance_info_param_name, {})
|
|
||||||
for instanceId in instanceId_list:
|
|
||||||
serializer = self.get_serializer(
|
|
||||||
instance=self.model.objects.get(**{f'{self.field_name}': instanceId}),
|
|
||||||
data=info,
|
|
||||||
partial=True
|
|
||||||
)
|
|
||||||
serializer.is_valid(raise_exception=True)
|
|
||||||
serializer.save()
|
|
||||||
return SuccessResponse(data=instanceId_list)
|
|
||||||
|
|
||||||
def delete(self, request: Request = None, *args, **kwargs):
|
|
||||||
self.model.objects.filter(**{f'{self.field_name}__in': request.data}).delete()
|
|
||||||
return SuccessResponse(data=request.data)
|
|
||||||
|
|
||||||
|
|
||||||
class ModelRelationshipAPIView(CustomAPIView):
|
|
||||||
"""
|
|
||||||
模型关联关系通用CRUD视图
|
|
||||||
"""
|
|
||||||
model = None
|
|
||||||
through_model = None
|
|
||||||
relationship_model = None
|
|
||||||
|
|
||||||
relationship_serializer = None
|
|
||||||
field_name: str = None
|
|
||||||
from_field_name: str = 'instanceId'
|
|
||||||
to_field_name: str = None
|
|
||||||
relationship_field_values = ()
|
|
||||||
|
|
||||||
view_logger_classes = [CustomerRelationshipViewLogger, ]
|
|
||||||
|
|
||||||
def get_relationship_data(self, instanceId: str):
|
|
||||||
relationship_model_field_name = self.relationship_field_values[0]
|
|
||||||
params = {}
|
|
||||||
params[self.field_name] = instanceId
|
|
||||||
business_key_dict = self.through_model.objects.filter(**params).values(
|
|
||||||
*self.relationship_field_values).distinct()
|
|
||||||
business_key_list = [ele[relationship_model_field_name] for ele in business_key_dict]
|
|
||||||
|
|
||||||
params = {}
|
|
||||||
params[f"{self.to_field_name}__in"] = business_key_list
|
|
||||||
queryset = self.relationship_model.objects.filter(**params)
|
|
||||||
|
|
||||||
data = ModelRelateUtils.model_to_dict(queryset, self.relationship_serializer, default=[])
|
|
||||||
if 'creator' in self.relationship_field_values and 'ctime' in self.relationship_field_values:
|
|
||||||
for _index in range(len(data)):
|
|
||||||
ele = data[_index]
|
|
||||||
ele['relationship_creator'] = business_key_dict[_index]['creator']
|
|
||||||
ele['relationship_ctime'] = business_key_dict[_index]['ctime']
|
|
||||||
return data
|
|
||||||
|
|
||||||
def execute_method(self, execute: str, request: Request, instanceId: str, *args, **kwargs):
|
|
||||||
method = request.method.lower()
|
|
||||||
fun = None
|
|
||||||
if execute == 'before':
|
|
||||||
fun = getattr(self, f'before_{method}', None)
|
|
||||||
elif execute == 'handle':
|
|
||||||
fun = getattr(self, f'handle_{method}', None)
|
|
||||||
elif execute == 'after':
|
|
||||||
fun = getattr(self, f'after_{method}', None)
|
|
||||||
if fun and isinstance(fun, (FunctionType, MethodType)):
|
|
||||||
fun(request, instanceId, *args, **kwargs)
|
|
||||||
|
|
||||||
def do_request(self, request: Request, instanceId: str, *args, **kwargs):
|
|
||||||
self.execute_method('before', request, instanceId, *args, **kwargs)
|
|
||||||
self.execute_method('handle', request, instanceId, *args, **kwargs)
|
|
||||||
self.execute_method('after', request, instanceId, *args, **kwargs)
|
|
||||||
self.handle_logging(request, instanceId=instanceId, *args, **kwargs)
|
|
||||||
data = self.get_relationship_data(instanceId)
|
|
||||||
return SuccessResponse(data)
|
|
||||||
|
|
||||||
def get(self, request: Request, instanceId: str, *args, **kwargs):
|
|
||||||
return self.do_request(request, instanceId, *args, **kwargs)
|
|
||||||
|
|
||||||
def post(self, request: Request, instanceId: str, *args, **kwargs):
|
|
||||||
return self.do_request(request, instanceId, *args, **kwargs)
|
|
||||||
|
|
||||||
def put(self, request: Request, instanceId: str, *args, **kwargs):
|
|
||||||
return self.do_request(request, instanceId, *args, **kwargs)
|
|
||||||
|
|
||||||
def delete(self, request: Request, instanceId: str, *args, **kwargs):
|
|
||||||
return self.do_request(request, instanceId, *args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class ModelRelationshipView(ModelRelationshipAPIView):
|
|
||||||
"""
|
|
||||||
模型关联关系通用CRUD视图
|
|
||||||
"""
|
|
||||||
|
|
||||||
def handle_get(self, request: Request, instanceId: str, *args, **kwargs):
|
|
||||||
data = self.get_relationship_data(instanceId)
|
|
||||||
return SuccessResponse(data)
|
|
||||||
|
|
||||||
def handle_post(self, request: Request, instanceId: str, *args, **kwargs):
|
|
||||||
relationship_model_field_name = self.relationship_field_values[0]
|
|
||||||
params = {}
|
|
||||||
params[f"{self.to_field_name}__in"] = request.data
|
|
||||||
queryset = self.relationship_model.objects.filter(**params)
|
|
||||||
|
|
||||||
exist_list = [getattr(ele, self.to_field_name) for ele in queryset]
|
|
||||||
bulk_info = []
|
|
||||||
for _id in exist_list:
|
|
||||||
info = {}
|
|
||||||
info[relationship_model_field_name] = _id
|
|
||||||
info[self.field_name] = instanceId
|
|
||||||
info['creator'] = request.user.username
|
|
||||||
bulk_info.append(self.through_model(**info))
|
|
||||||
self.through_model.objects.bulk_create(bulk_info)
|
|
||||||
data = self.get_relationship_data(instanceId)
|
|
||||||
return SuccessResponse(data)
|
|
||||||
|
|
||||||
def handle_put(self, request: Request, instanceId: str, *args, **kwargs):
|
|
||||||
relationship_model_field_name = self.relationship_field_values[0]
|
|
||||||
|
|
||||||
params1 = {}
|
|
||||||
params1[f"{self.field_name}"] = instanceId
|
|
||||||
params2 = {}
|
|
||||||
params2[f"{relationship_model_field_name}__in"] = request.data
|
|
||||||
|
|
||||||
relationships = self.through_model.objects.filter(**params1).exclude(**params2)
|
|
||||||
relationships.delete()
|
|
||||||
|
|
||||||
params = {}
|
|
||||||
params[f"{self.field_name}"] = instanceId
|
|
||||||
|
|
||||||
instanceId_dict = self.through_model.objects.filter(**params).values(*self.relationship_field_values).distinct()
|
|
||||||
instanceId_list = [ele.get(relationship_model_field_name) for ele in instanceId_dict]
|
|
||||||
create_list = list(set(request.data).difference(set(instanceId_list)))
|
|
||||||
for _id in create_list:
|
|
||||||
info = {}
|
|
||||||
info[relationship_model_field_name] = _id
|
|
||||||
info[self.field_name] = instanceId
|
|
||||||
info['creator'] = request.user.username
|
|
||||||
data = self.get_relationship_data(instanceId)
|
|
||||||
return SuccessResponse(data)
|
|
||||||
|
|
||||||
def handle_delete(self, request: Request, instanceId: str, *args, **kwargs):
|
|
||||||
relationship_model_field_name = self.relationship_field_values[0]
|
|
||||||
params = {}
|
|
||||||
params[f"{self.field_name}"] = instanceId
|
|
||||||
params[f"{relationship_model_field_name}__in"] = request.data
|
|
||||||
self.through_model.objects.filter(**params).delete()
|
|
||||||
data = self.get_relationship_data(instanceId)
|
|
||||||
return SuccessResponse(data)
|
|
||||||
|
|
|
@ -6,4 +6,5 @@ from ..models.save_file import SaveFile
|
||||||
from ..models.message_push import MessagePush
|
from ..models.message_push import MessagePush
|
||||||
from ..models.message_push import MessagePushUser
|
from ..models.message_push import MessagePushUser
|
||||||
from ..models.logininfor import LoginInfor
|
from ..models.logininfor import LoginInfor
|
||||||
|
from ..models.request_log import RequestLog
|
||||||
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
from django.db.models import TextField, CharField
|
|
||||||
|
|
||||||
from ...op_drf.models import CoreModel
|
|
||||||
|
|
||||||
|
|
||||||
class WebSet(CoreModel):
|
|
||||||
name = CharField(max_length=64, verbose_name="站点名称")
|
|
||||||
web_site = CharField(max_length=256, verbose_name="站点网址", null=True, blank=True)
|
|
||||||
logo = CharField(max_length=256, verbose_name="网站Logo", null=True, blank=True)
|
|
||||||
record_info = TextField(verbose_name="备案信息", null=True, blank=True)
|
|
||||||
statistics_code = TextField(verbose_name="统计代码", null=True, blank=True)
|
|
||||||
copyright_info = TextField(verbose_name="版权信息", null=True, blank=True)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = '操作日志'
|
|
||||||
verbose_name_plural = verbose_name
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"{self.name}"
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
from django.db.models import TextField, CharField, BooleanField
|
||||||
|
|
||||||
|
from ...op_drf.models import CoreModel
|
||||||
|
|
||||||
|
|
||||||
|
class RequestLog(CoreModel):
|
||||||
|
request_modular = CharField(max_length=64, verbose_name="请求模块", null=True, blank=True)
|
||||||
|
request_path = CharField(max_length=400, verbose_name="请求地址", null=True, blank=True)
|
||||||
|
request_body = TextField(verbose_name="请求参数", null=True, blank=True)
|
||||||
|
request_method = CharField(max_length=64, verbose_name="请求方式", null=True, blank=True)
|
||||||
|
request_msg = CharField(max_length=64, verbose_name="操作说明", null=True, blank=True)
|
||||||
|
request_ip = CharField(max_length=32, verbose_name="请求ip地址", null=True, blank=True)
|
||||||
|
request_browser = CharField(max_length=32, verbose_name="请求浏览器", null=True, blank=True)
|
||||||
|
response_code = CharField(max_length=32, verbose_name="响应状态码", null=True, blank=True)
|
||||||
|
request_location = CharField(max_length=32, verbose_name="操作地点", null=True, blank=True)
|
||||||
|
request_os = CharField(max_length=64, verbose_name="操作系统", null=True, blank=True)
|
||||||
|
json_result = TextField(verbose_name="返回信息", null=True, blank=True)
|
||||||
|
status = BooleanField(default=False, verbose_name="响应状态")
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = '操作日志'
|
||||||
|
verbose_name_plural = verbose_name
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.request_msg}[{self.request_modular}]"
|
|
@ -41,3 +41,6 @@ CORS_ORIGIN_ALLOW_ALL = True
|
||||||
CORS_ALLOW_CREDENTIALS = False
|
CORS_ALLOW_CREDENTIALS = False
|
||||||
# 验证码状态
|
# 验证码状态
|
||||||
CAPTCHA_STATE = True
|
CAPTCHA_STATE = True
|
||||||
|
# 操作日志配置
|
||||||
|
API_LOG_ENABLE = True
|
||||||
|
API_LOG_METHODS = ['POST', 'DELETE', 'PUT'] # 'ALL' or ['POST', 'DELETE']
|
||||||
|
|
Loading…
Reference in New Issue