使用MVC模型,无法将输出中的值获取到jinja2模板(python)中



当我加载flask应用程序时,不确定为什么我的变量是空的。。。

视图模型:

from flask import current_app
from app.viewmodels.shared.viewmodelbase import ViewModelBase
from app.infrastructure import redact_name
import canarytools, requests, json, urllib3
from os import path
from prettytable import PrettyTable
from requests.adapters import HTTPAdapter, Retry

class Canaries(ViewModelBase):
def __init__(self):
super().__init__()
self.title = "Canaries"
self.auth = "password"
self.console = canarytools.Console('user', 'password')
self.baseurl = "https://user.canary.tools/api/v1/devices/live"
self.payload = {
'auth_token': 'password'
}
self.flash_error()
self.get_live_birds()
self.get_dead_birds()
self.unackalerts()
def get_live_birds(self):
livebirds_table = PrettyTable()
livebirds_table.field_names = ["Name", "Location", "IP", "Uptime"]
for device in self.console.devices.live():
livebirds_table.add_row([device.name, device.location, device.ip_address, device.uptime_age])
livebirds_table.sortby = "Name"
html = livebirds_table.get_html_string()
return html
def get_dead_birds(self):
deadbirds_table = PrettyTable()
deadbirds_table.field_names = ["Name", "Location", "Personality", "Downtime"]
for device in self.console.devices.dead():
deadbirds_table.add_row([device.name, device.location, device.ippers, device.uptime_age])
deadbirds_table.sortby = "Name"
return deadbirds_table
def unackalerts(self):
unackalertnum = len(self.console.incidents.unacknowledged())
unackalerts_table = PrettyTable()
unackalerts_table.field_names = ["Type", "Attacker"]
for alert in self.console.incidents.unacknowledged():
alertcount = 0
unackalerts_table.add_row([alert.summary, alert.src_host])
if alertcount == unackalertnum:
exit(0) 
return unackalertnum

jinja2 html页面:

{% extends "base.html" %}
{% block app_content %}
<div class="container">
<table class="table table-hover table-striped w-auto" style="margin: auto">
<tbody>
<tr>
<td>{{ html | safe}}</td>
</tr>
</tbody>
</table>
</div>
{% endblock %}

视图:

from flask import render_template, session, g, current_app
from flask_login import current_user
import datetime
from app.bin.utils import log_request
from app.bin.auth_functions import login_required_with_ip_whitelist
from app.viewmodels.canaries.canaries_viewmodel import Canaries
from app.views.canaries import bp

@bp.before_request
def before_request():
session.permanent = True
current_app.permanent_session_lifetime = datetime.timedelta(hours=8)
session.modified = True
g.user = current_user

@bp.route("/canary/live_birds", methods=["GET"])
@login_required_with_ip_whitelist
def live_birds():
log_request()
vm = Canaries()
return render_template("canaries/live-birds.html", **vm.to_dict())

@bp.route("/canary/dead_birds", methods=["GET"])
@login_required_with_ip_whitelist
def dead_birds():
log_request()
vm = Canaries()
return render_template("canaries/dead-birds.html", **vm.to_dict())

当我打印时,我的Api变量html可以很好地打印到终端(金丝雀的Api(,但当我从Jinja2调用它时,它是空的,我可以将它转换为html,但当在我的Jinja2模板中使用它时,仍然不起作用

我被卡住了,那个开发出基于MVC模型的后端平台的人离开了公司!

视图模型基类:

class ViewModelBase:
def __init__(self, default_limit: int = 10):
self.request: Request = flask.request
self.request_dict: dict = request_dict.create("")
self.title: Optional[str] = "Security Ops"
self.error: Optional[str] = None
self.hide_nav: bool = hide_nav.get_hide_nav(self.request)
self.table_sm: bool = table_sm.get_table_sm(self.request)
self.hide_buttons: bool = hide_nav.get_hide_button(self.request)
self.hide_header: bool = False
self.redactable: bool = False
self.limitable: bool = False
self.limit: Optional[int] = utils.try_int(
self.request_dict.get("limit", default_limit)
)
self.dark_mode: bool = dark_mode.get_dark_mode_cookie(self.request)
def to_dict(self):
return self.__dict__
def flash_error(self):
if self.error:
flask.flash(self.error)

我的猜测是to_dict方法不会生成一个包含密钥htmldict

还有一些事情看起来很奇怪:

  • 在VM init中调用get_live_birdsget_dead_birds,而不是在需要时调用(即在view中(
  • 不将这些调用的结果分配给变量
  • get_live_birds生成一个html,而get_dead_birds返回PrettyTable的实例

UPDATE:在ViewModel类中,从__init__中删除对方法get_live_birds、get_dead_birds和uncallets的调用。因为它们的结果没有分配给self.xxx,所以在__init__上运行它们是没有用的。

然后你可以这样更新你的视图:

@bp.route("/canary/live_birds", methods=["GET"])
@login_required_with_ip_whitelist
def live_birds():
log_request()
vm = Canaries()
live_birds_html = vm.get_live_birds()
return render_template("canaries/live-birds.html",{"html": live_birds_html})

最新更新