Как рассчитать URL-адреса между приложениями в составном проекте Pyramid? - PullRequest
1 голос
/ 20 апреля 2019

Я использую Pyramid для разработки большого веб-проекта, состоящего из нескольких приложений, объединенных вместе с помощью функции составного приложения, и я хочу создать навигационные ссылки на моей домашней странице, чтобы указывать на различные приложения. Мой INI-файл начинается так:

[composite:main]
use = egg:Paste#urlmap
/ = home
/app1 = myapp1
/app2 = myapp2

[app:home]
use = egg:myproject#home

[app:myapp1]
use = egg:myproject#myapp1

[app:myapp2]
use = egg:myproject#myapp2

...

В данном приложении я использую request.route_url('view_name') для генерации URL-адресов, и код правильно добавляет / или /app1 или /app2 к любому URL-адресу, определенному в приложении config.add_route(...).

Я использую приложение home в качестве целевой страницы для веб-сайта по адресу /, и я хочу сделать что-то вроде request.route_url('app1.index') в шаблоне home, чтобы сгенерировать ссылку на представление index в app1. Однако, когда я пытаюсь это сделать, я получаю KeyError: 'No such route named app1.index' из шаблона.

Мой обходной путь - жестко закодировать пути в навигационные ссылки моей домашней страницы, но я бы предпочел этого не делать, поскольку эти пути уже определены в конфигурации .ini моего проекта.

Есть ли способ сделать это в Пирамиде?

1 Ответ

1 голос
/ 20 апреля 2019

Существует не стандартное решение.Подход, который я использовал лично, заключается в определении перекрестных ссылок между приложениями в моем конфигурационном файле, и я написал некоторый код для автоматической вставки их в мои приложения в виде статических маршрутов (см. static=True на config.add_route), который позволяет использовать request.route_url для генерации URL-адресов, внешних по отношению к вашему приложению.

Таким образом, я создаю конфигурацию, которая выглядит следующим образом:

[composite:main]
use = egg:Paste#urlmap
/ = home
/app1 = myapp1
/app2 = myapp2

[app:home]
use = egg:myproject#home
links =
    app1 /app1
    app2 /app2

[app:myapp1]
use = egg:myproject#myapp1
links =
    home /
    app2 /app2

[app:myapp2]
use = egg:myproject#myapp2
links =
    home /
    app1 /app1

Возможно, вам это покажется утомительным, но мне нравится контроль, который он обеспечивает на постоянной основе.основа приложения.В качестве альтернативы вы, вероятно, можете определить это в разделе [DEFAULT] файла и наследовать его между приложениями.

Идея состоит в том, что этот конфиг позволит мне выполнить request.route_url('app1').

Я используюэтот код (поместите его в файл с именем что-то вроде app_links.py и включите его через config.include('.app_links'):

from urllib.parse import urlparse

from pyramid.settings import aslist

def link_pregenerator(request, elements, kwargs):
    kwargs['_app_url'] = request.host_url
    return elements, kwargs

def includeme(config):
    settings = config.get_settings()

    links = aslist(settings.get('links', ''), flatten=False)
    for name, pattern in (item.split(' ', 1) for item in links):
        parsed = urlparse(pattern)
        if parsed.hostname:
            config.add_route(name, pattern, static=True)
        else:
            config.add_route(
                name, pattern,
                pregenerator=link_pregenerator,
                static=True,
            )
...