Повторное использование django URL-адресов шаблонов и представлений - PullRequest
0 голосов
/ 21 апреля 2020

У меня есть сценарий использования, в котором я хотел бы повторно использовать несколько существующих представлений и шаблонов URL.

Текущая ситуация - это продукт с примерно 20 представлениями:

urlpatterns = [
    #  product
        url(r'^product/(?P<pid>\d+)$', views.view_product, name='view_product'),
    url(r'^product/(?P<pid>\d+)/something$', views.view_something, name='view_something'),
    url(r'^product/(?P<pid>\d+)/morethings', views.view_morethings, name='view_morethings'),
    url(r'^product/(?P<pid>\d+)/deeper/things$',  views.view_deeper_things, name='view_deeper_things'),
...
etc.

Итак Я могу просмотреть следующие URL-адреса:

https://host/product/1
https://host/product/1/something
https://host/product/1/morethings
https://host/product/1/deeper/things

В новой ситуации я хочу добавить дополнительные способы просмотра продуктов, например, имя продукта или некоторую ключевую пару значений.

т.е.

https://host/product/name/product1
https://host/product/name/product1/something
https://host/product/name/product1/morethings
https://host/product/name/product1/deeper/things

и

https://host/product/meta/property1/value1
https://host/product/meta/property1/value1/something
https://host/product/meta/property1/value1/morethings
https://host/product/meta/property1/value1/deeper/things

, где я использую запрос к базе данных в представлении, чтобы найти продукт по имени или по указанному свойству + значение.

Как я могу повторно использовать шаблоны и представления, чтобы избежать появления 20 новых представлений и шаблонов для каждого способа идентификации продукта?

Я мог бы просто перечислить все (20x3) возможные шаблоны и добавить еще 20 для каждого нового способа идентификации продуктов.

    url(r'^product/(?P<pid>\d+)/something$', views.view_something, name='view_something'),
    url(r'^product/(?P<pid>\d+)/morethings', views.view_morethings, name='view_morethings'),
    url(r'^product/(?P<pid>\d+)/deeper/things$',  views.view_deeper_things, name='view_deeper_things'),

    url(r'^product/name/<str:name>/something$', views.view_something_name, name='view_something_name'),
    url(r'^product/name/<str:name>/morethings', views.view_morethings_name, name='view_morethings_name'),
    url(r'^product/name/<str:name>/deeper/things$',  views.view_deeper_things_name, name='view_deeper_things_name'),

    url(r'^product/meta/key/<str:name>/<str:name>/something$', views.view_something_meta, name='view_something_meta'),
    url(r'^product/meta/key/<str:name>/<str:name>/morethings', views.view_morethings_meta, name='view_morethings_meta'),
    url(r'^product/meta/key/<str:name>/<str:name>/deeper/things$',  views.view_deeper_things_meta, name='view_deeper_things_meta'),

Я знаю, что могу сделать:

urlpatterns = [
    #  product
        url(r'^product/(?P<pid>\d+)$', views.view_product, name='view_product'),
        url(r'^product/name/<str:name>$', views.view_product, name='view_product_by_name'),

И иметь параметры по умолчанию в представлении для pid и имени. Но это все равно потребовало бы, чтобы я указал шаблоны 20х3. И я бы посмотрел, работает ли «реверс». И я видел проблемы с отправкой сообщений по неправильному пути.

Я бы предпочел что-то вроде:

url(r'^product/((?P<pid>\d+)|(name/<str:name>)|meta/<str:key>/<str:value>$', views.view_product, name='view_product'),

Но я не думаю, что это сработает, и это сделает django невозможно вернуть что-то значимое для обратного?

Решение, которое у меня сейчас есть, состоит в том, чтобы иметь отдельный набор URL-адресов перенаправления с представлениями, которые ищут идентификатор продукта в базе данных и перенаправляют (302) браузер на исходный URL с идентификатором продукта.

path('s/product/name/<str:pname>', views.view_product_by_name,
    name='view_product_by_name'),

просмотр к / product / name / product1 приведет к перенаправлению на / product / 1

. Это работает, но требует много котельной плиты. код.

...