2014-05-06 2 views
4

Я работаю над большой платформой для публикации новостей. В основном перестроить все, начиная с нуля, с django. Теперь, когда мы почти готовы к запуску, мне нужно обработать перенаправленные URL-адреса. Каков наилучший способ сделать это, имея в виду, что мне приходится иметь дело с десятыми тысячами устаревших ссылок?Лучший способ обработки устаревших URL-адресов в django

Логика должна работать следующим образом: если ни один из существующих URL-адресов/совпадений, в которых они совпадают, не запускает этот URL-адрес, чтобы полностью восстановить устаревшие URL-адреса переадресации URL-адресов/просмотров, чтобы увидеть, может ли он перенаправить на новый URL-адрес перед возвратом ошибки 404.

Как это сделать?

+0

Либо вы хотите, чтобы отделить "унаследованных" URL в своем собственном urls.py или вы хотите Nginx переписывает. –

ответ

1

Awesome, добился того, что с помощью пользовательских межплатформенного:

from django.http import Http404 
from legacy.urls import urlpatterns 

class LegacyURLsMiddleware(object): 

    def process_response(self, request, response): 
     if response.status_code != 404: 
      return response 
     for resolver in urlpatterns: 
      try: 
       match = resolver.resolve(request.path[1:]) 
       if match: 
        return match.func(request, *match.args, **match.kwargs) 
      except Http404: 
       pass 
     return response 

Просто добавьте промежуточное программное обеспечение в качестве последнего промежуточного слоя в списке MIDDLEWARE_CLASSES. Затем используйте файл urls.py в своем устаревшем приложении, чтобы объявить устаревшие URL-адреса и представления, которые будут обрабатывать постоянные переадресации. НЕ включайте свои устаревшие URL-адреса в основную структуру URL-адресов. Это промежуточное программное обеспечение делает это для вас, но немного по-другому.

0

Возможно, вы захотите создать резервное представление, которое будет пытаться обработать любой URL-адрес, который не обрабатывается вашими шаблонами. Я вижу два варианта.

  1. Просто создайте шаблон «по умолчанию». Для этого шаблона важно, чтобы был последним в ваших urlpatterns!

    в вашем urls.py:

    urlpatterns = patterns(
        '', 
        # all your patterns 
        url(r'^.+/', 'app.views.fallback') 
    ) 
    

    в вашем views.py:

    from django.http.response import HttpResponseRedirect, Http404 
    
    def fallback(request): 
        if is_legacy(request.path): 
         return HttpResponseRedirect(convert(request.path)) 
        raise Http404 
    
  2. создать пользовательский HTTP 404 обработчика.

    в вашем urls.py:

    handler404 = 'app.views.fallback' 
    

    в вашем views.py

    from django.http.response import HttpResponseRedirect 
    from django.views.defaults import page_not_found 
    
    def fallback(request): 
        if is_legacy(request.path): 
         return HttpResponseRedirect(convert(request.path)) 
        return page_not_found(request) 
    

    это может показаться лучше решение, но он будет работать только если вы установите параметр DEBUG Ложь и предоставить пользовательский шаблон 404.

+0

@Simanas no, новые URL-адреса будут обрабатываться традиционным способом: вы просто объявляете шаблон для '/ whitepapers/6-way-to-make-your-life-better /' url с правильным обработчиком. И резервное представление попытается обработать старые: проверьте, является ли запрошенное представление устаревшим и перенаправляет его на новый эквивалент. – isobolev

+0

Ах да, вы правы, обработчик будет работать, но похоже, что он не предназначен для таких задач. – Simanas

0

Использование якобиана django-multiurl. Существует django ticket, чтобы решить проблему когда-нибудь, но на данный момент django-multiurl работает очень хорошо.

До:

# urls.py 
urlpatterns = patterns('', 
    url('/app/(\w+)/$', app.views.people), 
    url('/app/(\w+)/$', app.views.place), # <-- Never matches 
) 

После:

# urls.py 
from multiurl import multiurl, ContinueResolving 
from django.http import Http404 

urlpatterns = patterns('', multiurl(
    url('/app/(\w+)/$', app.views.people), # <-- Tried 1st 
    url('/app/(\w+)/$', app.views.place), # <-- Tried 2nd (only if 1st raised Http404) 
    catch=(Http404, ContinueResolving) 
)) 
Смежные вопросы