热门IT资讯网

【Python】Django页面渲染函数的一个小缺陷

发表于:2024-11-26 作者:热门IT资讯网编辑
编辑最后更新 2024年11月26日,总结python3中 filter() 返回的是可迭代对象,python2中 filter() 返回的是过原列表经过函数过滤后的新列表,也就是把原本Py2中的纯列表转为了更省内存的迭代器被filter

总结

python3中 filter() 返回的是可迭代对象,python2中 filter() 返回的是过原列表经过函数过滤后的新列表,也就是把原本Py2中的纯列表转为了更省内存的迭代器

  • 被filter修饰器过滤后的元组对象列表变为可以迭代的filter对象,
  • 渲染器无法识别filter对象,也无法识别把list(iterable_filter)直接带入到参数字典中,需要用表达式转一次

    缘由

    对传给render_to_string()函数的字典参数值中,包含了被filter函数过滤后的值,被渲染后,出现了信息缺失

    详细

    过滤器相关代码
def filter_muted_instance_item(format_alerts):    """屏蔽掉一个实例指定报警项"""    muted_instance_item = set(        [(i.ip, i.port, i.item) for i in AlertMute.objects.filter(start_time__lte=datetime.datetime.now(),                                                                  end_time__gte=datetime.datetime.now())])    filtered_set = filter(lambda x: (x.ip, x.port, x.item) not in muted_instance_item,  [format_alert for format_alert in format_alerts])    return filtered_set# # 定义修饰器 protype# def host_item_filter(alertor_func):#     @functools.wraps(alertor_func)#     def modifier(*args, **kwargs):#         kwargs['queryset'] = filter_muted_ip(kwargs['queryset'])#         alertor_func(**kwargs)#     return modifier# 定义修饰器,使用wrapt包简化代码def item_filter(filter_type='instance_item'):    @wrapt.decorator    def wrapper(wrapped, instance, args, kwargs):        if filter_type == 'ip_item':            kwargs['format_alerts'] = filter_muted_ip(kwargs['format_alerts'])        elif filter_type == 'instance_item':            kwargs['format_alerts'] = filter_muted_instance_item(kwargs['format_alerts'])        return wrapped(*args, **kwargs)    return wrapper
页面渲染相关代码
@item_filter(filter_type='instance_item')def mail_alert(alarm_type=None, format_alerts=None, scan_time=datetime.datetime.now(), **kwargs):    """    使用预置的邮件模板渲染后发送报警邮件    :param alarm_type: 报警类型    :param format_alerts: 警报结果集    :param scan_time: 警报产生时间    :param kwargs: 杂项参数    :return: 无返回项,程序内直接发送邮件    """    subject = "报警发送标题"    template = "报警发送预置HTML模板"    if alarm_type == 'dbagent_heartbeat':        template = 'dbAlertAPP/AgentHeartbeatAlarm.html'        subject = 'dbagent心跳报警'        elif:            ...........        else:            ..........    # 这里注意,被filter修饰器过滤后的元组对象列表变为可以迭代的filter对象,也就是把原本Py2中的纯列表转为了更省内存的迭代器    #         但是渲染器无法识别filter对象,也无法识别把list(iterable_filter)直接带入到参数字典中,需要用表达式转一次    result_list = list(format_alerts)    if kwargs.get("check_map"):        html_string = render_to_string(template, {"results": result_list,                                                  "scanTime": scan_time,                                                  "checkMap": kwargs.get("check_map")                                                  }                                       )    else:        html_string = render_to_string(template, {"results": result_list,                                                  "scanTime": scan_time,                                                  }                                       )    try:        send_mail(subject=environment_prefix+subject, message='plain_message', html_message=html_string,                  from_email=EMAIL_HOST_USER,                  recipient_list=get_recivers(), fail_silently=False)    except Exception as e:        p.error(e)
0