简体   繁体   English

Django URL 调度员 - 尝试下一个视图

[英]Django URL dispatcher - Try next view

Alright, let me give you guys an example;好吧,让我给你们举个例子;

We have the following url configuration in Django.我们在Django中有如下url配置。

Django will try to match the url with the rules down below. Django 将尝试将 url 与下面的规则匹配。 Once it finds a match, it will use the appropriate view and lookup the object in the model.一旦找到匹配项,它将使用适当的视图并在 model 中查找 object。

The thing is, once it finds a match in the URL pattern, it will match the view.问题是,一旦它在 URL 模式中找到匹配项,它就会匹配视图。 But once the object in the view can't be found, it will return a page not found (404) error.但是一旦找不到视图中的object,就会返回页面未找到(404)错误。

urls.py网址.py

from django.urls import path

from . import views

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

views.py视图.py

class ArticleByThemeView(ListView):
    """
    List all articles by a certain theme; "World War 2".
    """
    model = Article
    
    def dispatch(self, request, *args, **kwargs):
        try:
            # Check if the theme_slug matches a theme
            theme = ArticleTheme.objects.get(slug=self.kwargs['theme_slug'])
        except ArticleTheme.DoesNotExist:
            # Theme does not exist, slug must be an article_slug
            return redirect(
                'article_detail',
                category_slug=category_slug
                article_slug=theme_slug
            )
        return super().dispatch(request, *args, **kwargs)

class ArticleDetailView(DetailView):
    """
    Detailview for a certain article
    """
    model = Article

    def get_object(self):
        return get_object_or_404(
            Article,
            category__slug=self.kwargs['category_slug'],
            slug=self.kwargs['article_slug']
        )

We have the following url patterns, we can sort articles either by the editor or by theme.我们有以下 url 模式,我们可以按编辑或主题对文章进行排序。 We do this to create a logical url structure for SEO purposes.我们这样做是为了 SEO 目的创建逻辑 url 结构。

Is their any way we can redirect to another view once the object isn't found?一旦找不到 object,我们是否可以通过任何方式重定向到另一个视图?

Can we modify the dispatch method to return to the url patterns and find the following matching rule?能否修改dispatch方法返回url模式,找到如下匹配规则?

What about redirection like this:这样的重定向怎么样:

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)

Alright,好吧,

Based on the suggestion from Sunderam Dubey, I'wrote a function view, which uses two differn routes to the same view.根据 Sunderam Dubey 的建议,我写了一个 function 视图,它使用两条不同的路由到同一视图。

urls.py网址.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视图.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
        )

Todo:去做:

  • Remove one of the url routes删除其中一条 url 路线

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM