Django - Перенаправить слаг страницы на подробный просмотр - сокращение URL-адресов - PullRequest
1 голос
/ 28 мая 2020

Хорошо, у меня есть простая настройка со страницами, принадлежащими определенным категориям.

В моих URL-адресах у меня есть

path('<slug:category_slug>/', views.PageByCategoryView.as_view(), name='page_by_category'),
path('<slug:category_slug>/<slug:page_slug>/', views.PageDetailView.as_view(), name='page_detail'),

Так, например;

www.mywebsite.com/activities/cycling/

указывает на правильный подробный просмотр страницы о велосипеде.

Теперь я подумал, что было бы неплохо, если бы мы могли сократить URL как;

www.mywebsite.com/cycling/

Итак, я написал следующее представление:

def redirect_with_category(request, page_slug):
    '''
    This redirect view points to the canonical url
    '''
    page = get_object_or_404(Page, slug=page_slug)
    return redirect(page, permanent=True)

urls.py выглядит так:

path('<slug:category_slug>/', views.PageByCategoryView.as_view(), name='page_by_category'),
path('<slug:page_slug>/', views.redirect_with_category, name='page_detail_redirect'),
path('<slug:category_slug>/<slug:page_slug>/', views.PageDetailView.as_view(), name='page_detail'),

А теперь у нас проблемы, хотя редирект работает. Django перестает пытаться решить category_slug, если не может найти совпадения.

Каким-то образом, чтобы это работало, Django должен попытаться разрешить следующий путь, если он не найдет совпадения в category_slug .

Видимо Django выдает ошибку согласно документации; « или если на каком-либо этапе этого процесса возникает исключение, Django вызывает соответствующее представление обработки ошибок »

Можно ли как-нибудь решить эту проблему? Можно ли заставить Django искать следующие совпадающие результаты, если он не находит подходящего слага в первом URL-адресе?

Итак, я хочу перенаправить;

www.mywebsite.com/cycling/ К: www.mywebsite.com/activities/cycling/

1 Ответ

1 голос
/ 28 мая 2020

Причина, по которой это происходит, заключается в том, что path('<slug:page_slug>/, &hellip;) никогда не будет «срабатывать», поскольку каждый запрос, который вы делаете, «захватывается» path('<slug:category_slug>/, &hellip;), если вы сделаете полностью перекрывающиеся пути, последний из них будет никогда не будет срабатывать. В общем случае лучше сделать пути, которые не перекрывают вообще , так как это означает, что для перекрытия определенный путь недоступен, и кто-то может намереваться сделать его доступным.

Таким образом, вы должны выполнить сопоставление в представлении PageByCategoryView, и, если это дает «совпадение», выполнить, таким образом, redirect, вы можете сделать это, например, переопределив метод dispatch (или get, если вы используете только sh для перенаправления запросов GET).

from django.http import Http404
from django.shortcuts import get_object_or_404, redirect

class PageByCategoryView(ListView):

    # &hellip;

    def dispatch(self, *args, **kwargs):
        try:
            return super().dispatch(*args, **kwargs)
        except Http404:
            page = get_object_or_404(Page, <b>slug=self.kwargs['category_slug']</b>)
            return redirect(page)

Таким образом, мы сначала стремимся правильно обработать запрос, вызвав метод super().dispatch(*args, **kwargs). Если это возвращает 404, мы пытаемся найти Page, где slug равно category_slug, и перенаправляем туда. Если и это не поможет, будет возвращено 404.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...