Flas中的动态导航

2024-05-15 05:05:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个相当简单的网站在烧瓶工作,所有的动力来自一个sqlite数据库。每个页面都作为行存储在页面表中,该表保存诸如路径、标题和内容之类的内容。

该结构是分层的,页面可以有父级。例如,“about”可能是一个页面,也可能是“about/something”和“about/cakes”。因此,我想创建一个导航栏,其中包含指向父级为“/”(/是根页)的所有链接的链接。此外,我想它也显示了网页,是开放的和所有家长的网页。

例如,如果我们在“about/cakes/muffins”,除了总是显示的链接外,我们还会看到“about/cakes”的链接,其方式如下:

- About/
  - Cakes/
    - Muffins
    - Genoise
  - Pies/
- Stuff/
- Contact
- Legal
- Etc.[/]

对于那些有子级的页面,使用尾随斜线,而对于那些没有子级的页面,则不使用斜线

代码:

@app.route('/')
def index():
    page = query_db('select * from page where path = "/"', one=True)
    return render_template('page.html', page=page, bread=[''])

@app.route('/<path>')
def page(path=None):
    page = query_db('select * from page where path = "%s"' % path, one=True)
    bread = Bread(path)
    return render_template('page.html', page=page, crumbs=bread.links)

我已经觉得我在那里有两个功能违反了DRY。但是做导航会进一步破坏它,因为我也希望在错误页面上导航。

但我似乎找不到一个特别灵活的方法来做这件事。有什么想法吗?


Tags: pathapp网页内容链接defpage页面
2条回答

您可以在一个函数中通过使用多个decorator来实现:)

@app.route('/', defaults={'path': '/'})
@app.route('/<path>')
def page(path):
    page = query_db('select * from page where path = "%s"' % path, one=True)
    if path == '/':
        bread = Bread(path)
        crumbs = bread.links
    else:
        bread = ['']
        crumbs = None
    return render_template('page.html', page=page, bread=bread, crumbs=crumbs)

就我个人而言,我将修改bread函数,使其也适用于路径/

如果只是向上下文中添加变量,那么我建议查看上下文处理器:http://flask.pocoo.org/docs/templating/#context-processors

“flasky”和pythonic的方法是使用基于类的视图和模板层次结构

首先阅读这两种方法的文档,然后可以基于此方法重构代码:

class MainPage(MethodView):
    navigation=False
    context={}

    def prepare(self,*args,**kwargs):
        if self.navigation:
            self.context['navigation']={
                #building navigation
                #in your case based on request.args.get('page')
            }
        else:
            self.context['navigation']=None

    def dispatch_request(self, *args, **kwargs):
        self.context=dict() #should nullify context on request, since Views classes objects are shared between requests
        self.prepare(self,*args,**kwargs)
        return super(MainPage,self).dispatch_request(*args,**kwargs)

class PageWithNavigation(MainPage):
    navigation = True

class ContentPage(PageWithNavigation):
    def get(self):
        page={} #here you do your magic to get page data
        self.context['page']=page
        #self.context['bread']=bread
        #self.context['something_Else']=something_Else
        return render_template('page.html',**self.context)

然后您可以执行以下操作: 为main_page.html和page_with_navigation.html创建单独的页面 然后你的每个页面“error.html,page.html,somethingelse.html”都基于其中一个。 关键是要动态地执行此操作:

将稍微修改准备方法:

def prepare(self):
        if self.navigation:
            self.context['navigation']={
                #building navigation
                #in your case based on request.args.get('page')
            }
        else:
            self.context['navigation']=None
        #added another if to point on changes, but you can combine with previous one
        if self.navigation:
            self.context['extends_with']="templates/page_with_navigation.html"
        else:
            self.context['extends_with']="templates/main_page.html"

以及您的模板: 主页.html

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
    {% block navigation %}
    {% endblock %}
    {% block main_content %}
    {% endblock %}
</body>
</html>

带导航的网页.html

{% extends "/templates/main_page.html" %}

{% block navigation %}
        here you build your navigation based on navigation context variable, which already passed in here
{% endblock %}

page.html或其他任何页面。保持简单!
注意第一线。您的视图设置应该进入哪个页面,您可以通过设置navigation=of view类轻松地调整它。

{% extends extends_with %}

{% block main_content %}
        So this is your end-game page.
        Yo do not worry here about navigation, all this things must be set in view class and template should not worry about them
        But in case you need them they still available in navigation context variable
{% endblock %}

相关问题 更多 >

    热门问题