Канонические ссылки и 301 перенаправление, если URL-адрес не соответствует slug

Я пытаюсь реализовать схему URL, подобную переполнению стека в django / python.

например. ПК хранится в URL-адресе вместе со слизняком заголовка, поэтому для этого вопроса (id #4787731) URL-адрес

https://stackoverflow.com/questions/4787731/canonical-links-and-301-redirect-if-url-doesnt-match-slug

Если я позже изменю название (или просто вставлю какой-то случайный crud в url), то сайт все равно будет знать, какой вопрос я ищу (по идентификатору) и перенаправит 301 на правильный URL-например пытаться.

https://stackoverflow.com/questions/4787731/canonical-links-MODIFIED-URL

Так

  • каков наилучший способ включить канонические ссылки на мои страницы, такие как

(могу ли я использовать get_absolute_url)

  • каков наилучший способ признать, что текущий URL-адрес не соответствует канонической ссылке и выдает 301?

Примечание - этот вопрос аналогичен, но касается только случая генерация пули на лету или статически.

2 ответов


1: я не думаю, что есть смысл использовать канонический тег, если в любом случае есть 301.

давайте просто представим сценарий, в котором вы меняете URL-адрес с /q/111/hello-world to /q/111/foobar. Движки не будут предполагать, что они равны, если они не посещают исходный url-адрес с каноническим тегом на нем, указывающим на /q/111/foobar (что это не будет, потому что теперь это 301, разрывая любое доказательство связи между страницами).

2: я бы сделал это прямо вперед. Определять неуникальные slug поле и сравнить с захваченным URL-адресом в вашем подробном представлении.

# models
class MyModel(models.Model):
    # ...
    non_unique_slug = models.SlugField()

    def get_absolute_url(self):
        return "/questions/%s/%s" % (self.id, self.non_unique_slug)


# urls
    r'^questions/(?P<id>\d+)/(?P<slug>[\w-]+)/$' 

# views
def my_view(request, id, slug):
    page = Page.objects.get(id=id)
    if not slug == page.slug:
        return http.HttpResponsePermanentRedirect(page.get_absolute_url())

    # render page
    return direct_to_template(request, "foobar.html", {'page': page})

я следовал полезным инструкциям Юджи, но обнаружил, что вам нужно будет использовать HttpResponsePermanentRedirect объект для получения постоянного 301 вместо временного 302.