【问题标题】:Redirect url if slug does not match如果 slug 不匹配,则重定向 url
【发布时间】:2015-04-12 10:23:50
【问题描述】:

我想使用与 SO 相同的 url 模型。查找是通过 id 号完成的,但如果链接中存在错误的 slug,则会将重定向抛出到正确的页面。

示例: questions/4787731/whatever 将重定向到 questions/4787731/canonical-links-and-301-redirect-if-url-doesnt-match-slug。 我当前的代码通过 id 进行查找,但在出现错误的情况下不会重定向。 例子: 实体/12786676/whatever 应该重定向到 /entities/12786676/yellow-and-green-tree/。我确实正确获取了页面的内容,但我还希望重定向 url 以避免错误链接。 代码如下:

观看次数:

class EntityRedirectDetailView(RedirectView):
    def get(self, request, *args, **kwargs):
        pk = self.kwargs.get('pk', None)
        slug=self.kwargs.get('slug', None)
        entity = EntitiesNew.objects.get(pk=pk)
        self.url = '/entities/%s/%s' % (entity.pk, entity.slug)
        return super(EntityRedirectDetailView, self).get(request, *args, **kwargs)

网址:

urlpatterns = [
    url(r'^$', ListView.as_view(context_object_name = 'entities_list', queryset=EntitiesNew.objects.order_by('-id_number')[:500]), name='entities'),  
    url(r'^(?P<pk>\d+)/$', views.EntityRedirectDetailView.as_view(), name='entities-redirect'),  
    url(r'^(?P<pk>\d+)(?:/(?P<slug>[\w\d-]+))?/$', DetailView.as_view( model=EntitiesNew, context_object_name="entity"), name="entities-detail"),
]

谢谢

【问题讨论】:

  • 如果 URL 中只有一个 pk,则您的第二个模式匹配,因为它后面跟着 $,所以它永远不会匹配任何带有 slug 的 URL,无论正确与否。您可以做的是覆盖第三个模式的 DetailView 中的get,并在 slug 不正确时重定向。
  • 谢谢 Paulo,你是对的,第二个模式是只重定向一个 pk 匹配,因此如果 slug 错误就没有重定向......你能告诉我你通过覆盖 get 到底是什么意思吗方法?我试过了,但没有成功... if slug != entity.slug(): return redirect(entity, Permanent=True) ... 这段代码有问题吗?
  • 这是一般的想法,但你打电话给entity.slug,我想这是一个错字。您还重定向到entity,我没有足够的信息知道这是否正确。您在该模型中有get_absolute_url 方法吗?您还可以重定向到“实体详细信息”并传递参数。
  • 是的,我确实有 get_absolute_url:def get_absolute_url(self): return reverse('entities:entities-detail', kwargs={'pk':self.pk, 'slug':self.蛞蝓})
  • 那似乎是正确的。很抱歉另一个明显的问题,但您是否记得编辑urls.py 以使用新视图而不是您问题中的DetailView?无论如何,如果您编辑问题并为第三个模式添加完整视图,这可能会有所帮助。

标签: django redirect slug


【解决方案1】:

好的,我设法按照Paulo Almeida 的建议通过覆盖我的EntityDetailView(Detailview) 中的get 方法来做我想做的事。这是最终的代码。

urls.py:

url(r'^(?P<pk>\d+)/$', views.EntityRedirectDetailView.as_view(), name='entities-redirect'), 
    url(r'^(?P<pk>\d+)/(?P<slug>[-\w\d]+)/$', views.EntityDetailView.as_view(), name="entities-detail"),

views.py

class EntityRedirectDetailView(RedirectView):
    def get(self, request, *args, **kwargs):
        pk = self.kwargs.get('pk', None)
        slug=self.kwargs.get('slug', None)
        entity = EntitiesNew.objects.get(pk=pk)
        self.url = '/entities/%s/%s' % (entity.pk, entity.slug)
        return super(EntityRedirectDetailView, self).get(request, *args, **kwargs)

class EntityDetailView(generic.DetailView):
    """
        A DetailView which redirects to the absolute_url, if necessary.
    """
    template_name = 'entities/entitiesnew_detail.html'
    queryset = EntitiesNew.objects.get_queryset()
    def get_object(self, *args, **kwargs):
        # Return any previously-cached object
        pk = self.kwargs.get('pk', None)
        entity=EntitiesNew.objects.get(pk=pk)
        if getattr(self, 'entity', None):
            return self.entity
        return super(EntityDetailView, self).get_object(*args, **kwargs)
    def get(self, *args, **kwargs):
        # Make sure to use the canonical URL
        self.entity = self.get_object()
        obj_url = self.entity.get_absolute_url()
        if self.request.path != obj_url:
            return http.HttpResponsePermanentRedirect(obj_url)
        return super(EntityDetailView, self).get(*args, **kwargs);

在 models.py 我有 get_absoulte_url:

def get_absolute_url(self):
        return reverse('entities:entities-detail', kwargs={'pk':self.pk, 'slug':self.slug})

在模板中: {% url 'entities:entities-detail'entitiesnew.pk entitynew.slug %}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-14
    • 1970-01-01
    • 2018-01-06
    • 1970-01-01
    • 1970-01-01
    • 2012-08-05
    • 1970-01-01
    • 2019-05-05
    相关资源
    最近更新 更多