Django is a framework for Python web development. The architecture of MVC as a framework has been implemented. But you often have to make further abstractions when coding.
AOP is a development concept called aspect-oriented, which means that some functional code is dynamically loaded into the specified location at run time. The most common application is the dependency injection @autowired in spring.
The adorner can also be seen as an AOP implementation, but there are a few differences, let's take a look.
In our example we have views.py (in fact, controller layer) of Django removed the implement.py (Implementation) and decorator.py (adorner)
1, first look at our views.py.
Here we only give an interface as a demonstration.
#-*-coding:utf-8-*-ImportJSONImportLoggingImportImplementImportDecorator fromDjango.views.decorators.csrfImportCsrf_exemptlogger= Logging.getlogger (__name__)@csrf_exempt @decorator.impl_wrapper_check_time@decorator.process_time@decorator.cachedefalarm_month_daytotal (Request):ifRequest.method = ='GET': Time_str= Request. Get.get (' Time') returnImplement.alarm_month_daytotal (TIME_STR)
The Alarm_total interface does not return Jsonresponse object in function alarm_total in views.py, but instead returns the result of calling Implement.alarm_total () directly. It looks like Implement.alarm_total () returned to Jsonresponse.
, let's see if that's the case.
2, implement implementation layer
#-*-coding:utf-8-*-ImportJSONImportLoggingImportCalendar fromRedissImportRediscache fromConfigImportRedis_config, alarm_status_mapping, alarm_type_mapping, alarm_level_mapping, Combine_module, Alarm_module_ Mapping,alarm_stage_mapping, Alarm_type_config_mapping, month_total_closed_mapping, month_total_tosolve_mapping fromDatetimeImportdatetime, Timedelta fromDaoImportDao as Dash_dao fromExceptionsImportdataemptyexceptionImportTimelogger= Logging.getlogger (__name__)#get a day-by-month alarm situationdefalarm_month_daytotal (TIME_STR): Time_object= Datetime.strptime (Time_str,'%y-%m') month, length=Calendar.monthrange (time_object.year, time_object.month) ret_list= [0 forIinchrange (length) Items=dash_dao.get_alarms_by_month (TIME_STR)if notItems:RaiseDataemptyexception ('[table]%s'%'alarm_list_table') forIteminchItems:if notItem.alarm_time:Continueret_list[at_day (item.alarm_time)-1] + = 1R=Rediscache (redis_config) key_list= R.keys ("dmonitor:issue:%s*"%time_str)if notkey_list:returnret_list forKeyinchkey_list:content=r.get (key) Time_object= Datetime.strptime (Key.split (':') [2],'%y-%m-%d') Ret_list[time_object.day-1] = { 'y': ret_list[time_object.day-1], 'name': Content,'Marker': { 'symbol':'URL (/data_monitor/static/images/sun.png)' } } returnRet_list
No, Implement.alarm_total () only returns a list object. What is this for?
The reason is on the encapsulation of the several adorners.
3, Adorner decorator
Impl_wrapper_check_time (func): A Func method that performs decorative decorations, and jsonresponse encapsulation of the return
Process_time (func): Statistics execution time and print log
Cache (Func): Caching of requests to interfaces
Order of execution, the order of the adorner decorations, from the bottom up in our example is cache->process_time->impl_wrapper_check_time so:
1, first execute the beginning part of Impl_wrapper_check_time
2, then the start_time record of process_time time
3. Cache Caching Preparation
4, the function func is decorated
5. Cache Cached Return
6, Process_time the End_time record, and print the time log
7, Impl_wrapper_check_time return Jsonresponse
Exceptions are also thrown up at the first level in this order.
ImportLoggingImport TimeImportJSONImportTraceback fromRedissImportRediscache fromConfigImportRedis_config, Cache_timeout, Cache_switch fromExceptionsImportillegalparamexception fromDjango.httpImportJsonresponse fromDjango.httpImportHttpresponselogger= Logging.getlogger (__name__) Redis=Rediscache (redis_config)defImpl_wrapper_check_time (func):defWrapper (*args, * *Kwargs):Try: ifArgs[0].method = ='GET': if notArgs[0]. Get.get (' Time'): RaiseIllegalparamexception (' Time') Data= Func (*args, * *Kwargs)returnJsonresponse ({'errno': 0,'msg':'Success','Data': Data}) exceptException, Ex:logger.error (Traceback.format_exc ())returnJsonresponse ({'errno':-1,'msg': Str (ex)}) returnwrapperdefProcess_time (func):defWrapper (*args, * *Kwargs): Path=Args[0].get_full_path () start_time=time.time () data= Func (*args, * *Kwargs) End_time=time.time () logger.info ('path:%s, Process_time:%s Ms'% (path, str (end_time-start_time) * 1000))) returnDatareturnwrapperdefCache (func):defWrapper (*args, * *Kwargs):if notCache_switch:data= Func (*args, * *Kwargs)returnData Path=Args[0].get_full_path () Dashboard_cache_key='dashboard:cache:%s'%PathifRedis.get (Dashboard_cache_key): Logger.info ('[hit Cache] path:%s'%path)returnjson.loads (Redis.get (dashboard_cache_key)) data= Func (*args, * *Kwargs) Redis.set (Dashboard_cache_key, Json.dumps (data)) Redis.expire (Dashboard_cache_key, Cache_timeout ) Logger.info ('[Query] path:%s'%path)returnDatareturnWrapper
Python uses adorners @ functional Django Development