Python 3.10 的 Flask Nav / 导航替代方案
Flask Nav / Navigation Alternative for Python 3.10
我目前正在制作一个 Flask 项目,但我需要能够在 render_template() return 页面时根据变量动态生成不同的导航栏。
更具体地说,我的目标是在以下情况下动态创建/ return 导航栏 1. 用户登录更改登录到帐户菜单 2. 类别的自层次结构(父类别FK ref in child node IF parent is root then FK is root) on a menu.
我对Flask还是个新手,但我一直在研究这件事,发现了Flask-Nav或Flask Navigation。这两个都不适合我,因为我在 Python 3.10 上是 运行,并且这两个库只在 Python 3.9 之前受支持。这是因为 Python 3.10 不支持可变序列。
lass ItemCollection(collections.MutableSequence,
AttributeError: module 'collections' has no attribute 'MutableSequence'
是否有任何其他我可以使用的库或方法。我非常想生成我自己的 HTML 和 return,我一直坚持如何在实际模板之上说 return 导航 html 代码和将该代码放入靠近顶部但低于头部信息的导航位置。
string nav = '<NAV class='NavBar'><LINKS></NAV>'
return render_template('index.html', nav)
当用户登录时,您将用户详细信息分配给一个参数并将该参数传递回您的 front-end (html)。在您的前端,使用 JINJA2 检查参数是否存在。如果存在,显示 html 以获得帐户详细信息,否则显示登录 link。
粗略的样本是
html
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<!-- If user parameter exists, display Account and drop down -->
{% if user %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{user.email}}
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#">Action 1</a>
<a class="dropdown-item" href="#">Action 2</a>
</div>
</li>
{% else %}
<!-- User parameter does not exist so display login link -->
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">Login</span></a>
</li>
{% endif %}
</div>
</nav>
解决这个问题的方法可能是使用上下文处理器,它可以将变量注入每个路由...
from flask import Flask, render_template, url_for
app = Flask(__name__)
@app.context_processor
def inject_dict_for_all_templates():
""" Build the navbar and pass this to Jinja for every route
"""
# Build the Navigation Bar
nav = [
{"text": "Homepage", "url": url_for('index')},
{"text": "About Page", "url": url_for('about')},
{
"text": "More",
"sublinks": [
{"text": "Stack Overflow", "url": "https://whosebug.com"},
{"text": "Google", "url": "https://google.com/"},
],
},
# {'text':'Github','url':'https://github.com/'}
]
# sticking with the Flask login example
if current_user.is_authenticated:
# Show the user's name
nav.append({'text': f'Logged in as {current_user.name}', 'url': url_for('profile')})
else:
# Show the login link
nav.append({'text': 'Login', url_for('login')})
return dict(navbar = nav)
当然,这里url_for
函数是用来生成一些链接的,所以你也需要那些对应的路由...
@app.route('/')
def index(): return render_template('index.html')
@app.route('/about')
def about(): return render_template('about.html')
如果您使用 Flask-Login
之类的东西并且可以访问 currentuser
变量,您可能可以将其包含在 nav
词典列表中的某处。 (也许@NoCommandLine 的回答有更好的变量名信息)
这与 Bootstrap 的 navbar component 兼容,模板代码如下所示...
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">{{config['SITE_TITLE']}}</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
{% for item in navbar %}
{% if item.sublinks %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{item.text}}
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
{% for sublink in item.sublinks %}
<a class='dropdown-item' href="{{sublink.url}}">{{sublink.text}}</a>
{% endfor %}
</div>
</li>
{% elif item.url %}
<li class="nav-item">
<a class="nav-link" href="{{item.url}}">{{item.text}}</a>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
</nav>
呈现时,这会为您提供如下内容:
我已经创建了 a gist,其中包含基础模板和索引模板,以及正确的 CDN 链接以实现此功能。
我目前正在制作一个 Flask 项目,但我需要能够在 render_template() return 页面时根据变量动态生成不同的导航栏。
更具体地说,我的目标是在以下情况下动态创建/ return 导航栏 1. 用户登录更改登录到帐户菜单 2. 类别的自层次结构(父类别FK ref in child node IF parent is root then FK is root) on a menu.
我对Flask还是个新手,但我一直在研究这件事,发现了Flask-Nav或Flask Navigation。这两个都不适合我,因为我在 Python 3.10 上是 运行,并且这两个库只在 Python 3.9 之前受支持。这是因为 Python 3.10 不支持可变序列。
lass ItemCollection(collections.MutableSequence, AttributeError: module 'collections' has no attribute 'MutableSequence'
是否有任何其他我可以使用的库或方法。我非常想生成我自己的 HTML 和 return,我一直坚持如何在实际模板之上说 return 导航 html 代码和将该代码放入靠近顶部但低于头部信息的导航位置。
string nav = '<NAV class='NavBar'><LINKS></NAV>'
return render_template('index.html', nav)
当用户登录时,您将用户详细信息分配给一个参数并将该参数传递回您的 front-end (html)。在您的前端,使用 JINJA2 检查参数是否存在。如果存在,显示 html 以获得帐户详细信息,否则显示登录 link。
粗略的样本是
html
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<!-- If user parameter exists, display Account and drop down -->
{% if user %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{user.email}}
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#">Action 1</a>
<a class="dropdown-item" href="#">Action 2</a>
</div>
</li>
{% else %}
<!-- User parameter does not exist so display login link -->
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">Login</span></a>
</li>
{% endif %}
</div>
</nav>
解决这个问题的方法可能是使用上下文处理器,它可以将变量注入每个路由...
from flask import Flask, render_template, url_for
app = Flask(__name__)
@app.context_processor
def inject_dict_for_all_templates():
""" Build the navbar and pass this to Jinja for every route
"""
# Build the Navigation Bar
nav = [
{"text": "Homepage", "url": url_for('index')},
{"text": "About Page", "url": url_for('about')},
{
"text": "More",
"sublinks": [
{"text": "Stack Overflow", "url": "https://whosebug.com"},
{"text": "Google", "url": "https://google.com/"},
],
},
# {'text':'Github','url':'https://github.com/'}
]
# sticking with the Flask login example
if current_user.is_authenticated:
# Show the user's name
nav.append({'text': f'Logged in as {current_user.name}', 'url': url_for('profile')})
else:
# Show the login link
nav.append({'text': 'Login', url_for('login')})
return dict(navbar = nav)
当然,这里url_for
函数是用来生成一些链接的,所以你也需要那些对应的路由...
@app.route('/')
def index(): return render_template('index.html')
@app.route('/about')
def about(): return render_template('about.html')
如果您使用 Flask-Login
之类的东西并且可以访问 currentuser
变量,您可能可以将其包含在 nav
词典列表中的某处。 (也许@NoCommandLine 的回答有更好的变量名信息)
这与 Bootstrap 的 navbar component 兼容,模板代码如下所示...
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">{{config['SITE_TITLE']}}</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
{% for item in navbar %}
{% if item.sublinks %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{item.text}}
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
{% for sublink in item.sublinks %}
<a class='dropdown-item' href="{{sublink.url}}">{{sublink.text}}</a>
{% endfor %}
</div>
</li>
{% elif item.url %}
<li class="nav-item">
<a class="nav-link" href="{{item.url}}">{{item.text}}</a>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
</nav>
呈现时,这会为您提供如下内容:
我已经创建了 a gist,其中包含基础模板和索引模板,以及正确的 CDN 链接以实现此功能。