dash构建多页应用

发布时间 2023-07-17 13:26:54作者: meizhengchao

dash 构建多页面应用一种方案

本方案对dash官网多页面案例使用dash_bootstrap_components案例进行优化与测试,效果如下

项目代码结构如下

│  app.py
│
├─assets
│  │  assets_file.py
│  │  __init__.py
│
└─pages
    │  page_analytics.py
    │  page_home.py
    │  __init__.py

assets/assets_file.py 用来指定样式

"""
指定样式
"""

SIDEBAR_STYLE = {
    "position": "fixed",
    "top": 0,
    "left": 0,
    "bottom": 0,
    "width": "16rem",
    "padding": "2rem 1rem",
    "background-color": "#f8f9fa",
}

# the styles for the main content position it to the right of the sidebar and
# add some padding.
CONTENT_STYLE = {
    "margin-left": "18rem",
    "margin-right": "2rem",
    "padding": "2rem 1rem",
}

pages/page_home.py 多页应用中的一页

import dash
from dash import html
from assets.assets_file import CONTENT_STYLE

# 注册pages
dash.register_page(__name__, path='/')

layout = html.Div(
    children=[
        html.H1(children='This is our Home page'),
        html.Div(children='''This is our Home page content.'''),
    ],
    style=CONTENT_STYLE  # 指定样式
)

pages/page_analytics.py 多页应用中的另一页,同时验证callback

import dash
from dash import html, dcc, callback, Input, Output
from dash_daq import BooleanSwitch
from assets.assets_file import CONTENT_STYLE

# 注册pages
dash.register_page(__name__)

layout = html.Div(
    children=[
        html.H1(children='This is our Analytics page'),
        html.Div([
            "Select a city: ",
            dcc.RadioItems(['New York City', 'Montreal', 'San Francisco'],
                           'Montreal',
                           id='analytics-input')
        ]),
        html.Br(),
        html.Div(id='analytics-output'),
        html.Br(),
        html.Div(BooleanSwitch(id='switch', on=False, label="开关", labelPosition="top",style={"float": "left"}))
    ],
    style=CONTENT_STYLE
)


# page_file.py 内写的callback也可以正常使用
@callback(
    Output('analytics-output', 'children'),
    Input('analytics-input', 'value')
)
def update_city_selected(input_value):
    return f'You selected: {input_value}'

app.py

from dash import Dash, html, dcc, Output, Input
import dash
import dash_bootstrap_components as dbc
import dash_auth
from assets.assets_file import SIDEBAR_STYLE, CONTENT_STYLE


class App(Dash):
    def __init__(self, *arg, **kwarg):
        super().__init__(*arg, **kwarg)

        self.layout = html.Div(
            [
                dcc.Location(id="url"),
                html.Div(
                    [
                        html.H2("Sidebar", className="display-4"),
                        html.Hr(),
                        html.P("A simple sidebar layout with navigation links", className="lead"),
                        dbc.Nav([
                            dbc.NavLink(f"{page['name']} - {page['path']}", href=page["relative_path"],
                                        active="exact") for page in dash.page_registry.values()
                        ],
                            vertical=True,
                            pills=True,
                        ),
                    ],
                    style=SIDEBAR_STYLE,
                ),
                html.Div(id="page-content", style=CONTENT_STYLE),
                dash.page_container
            ],
        )

        # 添加callback
        self.callback(Output('switch', 'label'), Input('switch', 'on'))(self.func_test)

    def func_test(self, on):
        """
        测试page_file.py 内的元素能否触发回调  -> 可以触发
        :param on:
        :return:
        """
        if on:
            return '这是开关,当前开关开'
        else:
            return '这是开关,当前开关关'


if __name__ == '__main__':
    VALID_USERNAME_PASSWORD_PAIRS = {'user': 'pwd'}  # 本地账户密码储存
    app = App(
        name=__name__,
        assets_folder='assets',  # 对应资源存放目录,可下载后解压到这里
        title='app',
        update_title='Loading...',
        use_pages=True,
        pages_folder='pages',  # 对应的pages存放的目录
    )
    auth = dash_auth.BasicAuth(app, VALID_USERNAME_PASSWORD_PAIRS)  # 添加用户登录
    app.run_server()