【问题标题】:Redirects clashing with URL patterns Django重定向与 URL 模式冲突 Django
【发布时间】:2016-04-11 19:13:11
【问题描述】:

我正在尝试让 Django 的重定向应用程序正常工作,它适用于我在数据库中的一些重定向,但不是全部。

那些与我的 url 模式之一匹配的 404 没有重定向,其余的都很好。

urlpatterns = [
    ...
    url(r'^(?P<category>[-\w]+)/$', views.SubCategoryListView.as_view(),
        name='category_list'),
    url(r'^(?P<category>[-\w]+)/(?P<slug>[-\w]+)/$', 
        views.content_or_sub_category, name='choice')
    ...
]

例如,假设 URL 'example.com/foo/bar' 应该重定向。它将匹配上面的第二个 url 模式,被发送到content_or_sub_category,它会检查 'foo' 是否是一个有效的类别,以及 'bar' 是否是一个有效的 slug。在发现它们不是时,它会 404(如下面的代码所示)并且不会重定向。

在文档中说

每当任何 Django 应用程序引发 404 错误时,此中间件都会在重定向数据库中检查请求的 URL,作为最后的手段。

https://docs.djangoproject.com/en/1.8/ref/contrib/redirects/

但是,它不会在任何时候引发 404 时进行重定向,而是似乎只有在 Django 找不到匹配模式时才会发生。

这是它应该表现的方式吗?

我发现这个问题Raise 404 and continue the URL chain 是关于如何在一个 404 时继续评估其余的 url 模式,但看起来这是你不能或不应该做的事情。

该问题的唯一答案建议在您的 urls.py 中添加一些逻辑,但这需要检查 URL 的有效性,然后根据其是否有效来制作 urlpatterns 列表。我在 urls.py 中搜索并找不到方法。

我正在使用 Django 1.8。

class SubCategoryListView(ListView):
    model = Content
    queryset = Content.objects.published()
    paginate_by = 15

    def get_queryset(self):
        qs = super(SubCategoryListView, self).get_queryset()
        if 'category' in self.kwargs:
            if self.kwargs['category'] is not None:
                qs = qs.filter(
                    categories__slug__contains=self.kwargs['category'])
        return qs

    def get_context_data(self, **kwargs):
        context = super(SubCategoryListView, self).get_context_data(**kwargs)

        if 'category' in self.kwargs and self.kwargs['category'] is not None:
            context['category'] = get_object_or_404(Category,
                                                    slug=self.kwargs[
                                                            'category'])
return context

...

def content_or_sub_category(self, **kwargs):
    sub_category = get_object_or_false(Category.objects.sub_categories(),
                                       slug=kwargs['slug'])
    content = get_object_or_false(Content.objects.published(),
                                  slug=kwargs['slug'])
    if content:
        return ContentDetailView.as_view()(self, **kwargs)
    if sub_category:
        return ContentListView.as_view()(self,
                                         **{'category': kwargs['category'],
                                            'sub_category': kwargs['slug']})
    raise Http404

一些无效的重定向:

/46421 --> /economy/has-prime-minister-broken-promise-tax-credits/
/are-living-standards-on-the-rise --> /economy/are-living-standards-rise/
/articles/nhs_budget_cut-28646    --> /economy/has-nhs-budget-been-cut/

但这样的事情确实有效:

/health/live/2015/jan/number_12_hour_wait_hospital_bed_accident_emergency-38409 --> /health/spike-numbers-waiting-12-hours-e-hospital-bed/

【问题讨论】:

  • 中间件适用于任何 404,而不仅仅是在未找到模式时。您可以显示重定向的 db 条目吗?
  • 这就是我的想法,考虑到文档所说的内容。添加了一些示例,因为有超过 6000 个,所以无法全部展示。

标签: python django python-3.x django-urls django-1.8


【解决方案1】:

不确定return ContentDetailView.as_view()(self, **kwargs) 是什么,但一般来说,如果你想重定向,你会使用类似的东西:

return redirect(reverse('category_list', args=[ARG1, ARG2]))

其中 "category_list" 是 url 模式的名称,ARG1 和 ARG2 是您想要在 url 中使用的参数。

【讨论】:

  • 没问题!如果这是正确答案,请务必点击我答案左侧的复选标记,以便任何偶然发现此主题的人都知道该怎么做
  • 不完全是,return ContentDetailView.as_view()(self, **kwargs) 工作正常,但您的版本更清晰。 不起作用的事情是使用重定向应用程序从页面的旧网址重定向到新网址。
猜你喜欢
  • 2015-06-13
  • 1970-01-01
  • 2016-11-18
  • 1970-01-01
  • 2023-03-12
  • 2022-01-10
  • 2020-07-09
  • 1970-01-01
  • 2019-02-11
相关资源
最近更新 更多