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

18 浏览
0 Comments

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

我们在Django中有以下的URL配置。

Django将尝试将URL与下面的规则匹配。一旦找到匹配项,它将使用适当的视图并在模型中查找对象。

问题是,一旦在URL模式中找到匹配项,它将匹配视图。但是一旦无法找到视图中的对象,它将返回一个页面找不到(404)错误。

urls.py:

from django.urls import path
from . import views
urlpatterns = [
    path('articles///', views.ArticleByThemeView.as_view(), name='articles_by_editor'),
    path('articles///', views.ArticleDetailView.as_view(), name='articles_by_theme')
]

views.py

class ArticleByThemeView(ListView):
    """
    列出所有关于特定主题(“二战”)的文章。
    """
    model = Article
    def dispatch(self, request, *args, **kwargs):
        try:
            # 检查theme_slug是否与一个主题匹配
            theme = ArticleTheme.objects.get(slug=self.kwargs['theme_slug'])
        except ArticleTheme.DoesNotExist:
            # 主题不存在,slug必须是文章的slug
            return redirect(
                'article_detail',
                category_slug=category_slug
                article_slug=theme_slug
            )
        return super().dispatch(request, *args, **kwargs)
class ArticleDetailView(DetailView):
    """
    特定文章的详细视图
    """
    model = Article
    def get_object(self):
        return get_object_or_404(
            Article,
            category__slug=self.kwargs['category_slug'],
            slug=self.kwargs['article_slug']
        )

我们有以下的URL模式,我们可以按编辑者或主题对文章进行排序。我们这样做是为了为SEO目的创建一个逻辑的URL结构。

一旦找不到对象,我们有没有办法重定向到另一个视图?

我们可以修改dispatch方法以返回到URL模式并找到下一个匹配规则吗?

0
0 Comments

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

在问题中,我写了一个函数视图,它使用了两个不同的路由指向同一个视图。

urls.py:

from django.urls import path
from . import views
urlpatterns = [
    path('articles///', views.article_theme_or_detail_view, name='article_by_theme'),
    path('articles///', 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路由即可。

0
0 Comments

问题出现的原因是在重定向时,发生了重定向循环。具体原因可能是因为在函数`articles_by_editor`中的`redirect`函数的参数`category`没有正确传递,导致每次重定向都会返回到相同的视图`articles_by_theme`,从而形成了循环。

解决方法是确保在重定向时正确传递参数`category`。可以通过修改`redirect`函数的参数来解决这个问题,如下所示:

return redirect('articles_by_theme', kwargs={'category': category})

这样,每次重定向时都会将正确的`category`参数传递给视图`articles_by_theme`,避免了重定向循环的问题。

另外,在`articles_by_theme`视图中也要确保没有发生重定向循环。可以通过检查重定向的目标是否与当前视图相同来避免循环,如下所示:

def articles_by_theme(request, category):
    if category == 'current_category':
        return HttpResponse('This is the current category page.')
    else:
        # perform other operations

通过以上修改,应该能够解决重定向循环的问题。

0