如果 slug 不匹配则重定向 url

Redirect url if slug does not match

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

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

观看次数:

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)

urls:

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"),
]

谢谢

好的,根据 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 entitiesnew.slug %}