Django URL dispatcher - Попробуйте следующий вид

Хорошо, позвольте мне привести вам пример, ребята;

У нас есть следующая конфигурация url в Django.

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

Дело в том, что как только он находит совпадение в шаблоне URL, он сопоставляет представление. Но как только объект в представлении не может быть найден, он вернет ошибку "Страница не найдена" (404).

#urls.py

from django.urls import path

from . import views

urlpatterns = [
    path('articles/<slug:category>/<slug:editor>/', views.articles_by_editor),
    path('articles/<slug:category>/<slug:theme>/', views.articles_by_theme)
]

У нас есть следующие шаблоны url, мы можем сортировать статьи либо по редактору, либо по теме. Мы делаем это для создания логической структуры url для SEO целей.

Есть ли способ перенаправить нас на другое представление, если объект не найден?

Можем ли мы модифицировать метод dispatch так, чтобы он возвращался к шаблонам url и находил следующее правило соответствия?

А как насчет перенаправления следующим образом:

def articles_by_editor(request, category, editor):
    try:
        article = Article.objects.get(category=category, editor=editor)
        # return article
    except Article.DoesNotExist:
        # redirect to another view
        return redirect('articles_by_theme', category=category)

Правильно,

Основываясь на предложении Sunderam Dubey, я написал функцию представления, которая использует два разных маршрута к одному и тому же представлению.

urls.py

from django.urls import path

from . import views

urlpatterns = [
    path('articles/<slug:category>/<slug:slug>/', views.article_theme_or_detail_view, name='article_by_theme'),
    path('articles/<slug:category>/<slug:slug>/', views.article_theme_or_detail_view, name='article_detail')

]

views.py

def article_theme_or_detail_view(
    request,
    category_slug,
    slug=None
):
    """
    This view could either be for a theme view or detailview,
    depending on the slug.
    """
    try:
        # Check if the slug represents a theme
        theme = ArticleTheme.objects.get(slug=slug)
        article_list = Article.object.filter(theme=theme)
        
        # Add context
        context = {
            'theme': theme,
            'article_list': article_list
        }

        # Render the template with context
        return render(
            request,
            'article_by_theme.html',
            context
        )
    except ArticleTheme.DoesNotExists:
        # The theme does not exist so the slug must be for a detail view
        context = {
            article = Article.objects.get(slug=slug)
        }

        return render(
            request,
            'article_detail.html',
            context
        )

Тодо:

  • Удалите один из url-маршрутов
Вернуться на верх