2016-12-24 20 views
0

Я конвертирую сайт электронной коммерции как регион (например, США, ЕС), поэтому он будет в основном чувствовать себя как другой сайт для посетителей на основе контента они увидят, хотя это на самом деле один сайт (по многим причинам). Большинство путей на моем сайте станут специфичными для региона, путем префикса с областью в начале пути, например, '/ us /' (я мог бы преобразовать все, но если это значительно упростило).В Django, как добавить региональный префикс к большинству контуров

Мой план:

  • Middleware идентифицирует области на основе 1) запроса пути, 2) сессии, или 3) гадать на основе IP-адреса в указанном порядке, и он установлен на объекте запроса. Кроме того, как только они используют региональный путь, он получает значение сеанса. Таким образом, контекст региона переносится через URL-адреса, которые не относятся к региону.

  • URL-шаблоны, специфичные для региона, должны обновляться в соответствии с областью, хотя я уже обнаружил регион в промежуточном программном обеспечении, поскольку логика была сложнее, чем просто путь. Тем не менее, я должен сделать это параметром и переходить во все мои взгляды по следующей причине (реверсирование). Кроме того, любой путь, который становится региональным, будет иметь свои предыдущие шаблоны 301, перенаправляющие их региональные пути.

  • Для создания ссылок, которые относятся к региону, мне нужно обновить многие вызовы reverse() и {% url%}, добавив аргумент region. Хотелось бы, чтобы там был какой-то слой, который я мог бы настроить для динамического изменения URL-адресов со знанием запроса.

Мой основной вопрос - лучший способ справиться с реверсированием (последняя пуля). Он чувствует себя как много ненужной работы. Я открыт для лучших способов решения проблемы в целом.

Обновления:

  • Я исключил поддомены, потому что они, как известно, плохо для SEO, передачи полномочий. Кроме того, я думаю, что субдомены могут подразумевать совершенно разные настройки, тогда как пока я буду управлять этим как единым webapp.
  • Как указывает @RemcoGerlich, в основном я хочу добавить автоматическое поведение, которое LocaleMiddleware/i18n_patterns добавляет как в urlconf, так и в обратном направлении.

ответ

2

Я придумал несколько способов сделать это (четвертый - бонус с использованием поддоменов). Все предполагают промежуточное ПО, которое обнаруживает регион и задает его по запросу.

  1. Следующее сообщение @ RemcoGerlich, имитирует, как Django обрабатывает интернационализацию URL-адресов. LocaleMiddleware определяет язык и устанавливает активный язык в этом запросе (с локальной переменной потока).Затем этот активный язык используется для формирования URL-адресов с помощью i18n_patterns(), который фактически возвращает LocaleRegexURLResolver (который подклассифицирует обычный резольвер) вместо URL-адресов. Я считаю, что что-то подобное можно было бы сделать для поддержки других типов префиксов.

  2. Более грубый подход заключается в том, чтобы снова сохранить регион не только в запросе, но и снова в локальной переменной потока, как Django для активного языка. Обновите URL-адреса, чтобы иметь именованный аргумент для префикса региона и добавлять к нему аргументы. Внесите пользовательский реверс, чтобы добавить параметр области. Если вы склонны делать зло, это может быть обезврежено, чтобы не касаться всех ссылок reverse и url.

  3. Используйте промежуточное программное обеспечение до set the request.urlconf на основе региона, чтобы переопределить ROOT_URLCONF. Это обеспечивает целый набор URL-адресов только для этого запроса. Создайте один новый URLconf для каждого региона, который добавит свой префикс, а затем включит базовый URLconf. Нет необходимости фиксировать часть участка пути или беспорядок с параметрами представления. Реверсирование URL-адресов «просто работает».

  4. Если вы хотите использовать субдомены, которых я не сделал, есть приложение Django под названием django-hosts, как указано в этом вопросе: Django: Overwrite ROOT_URLCONF with request.urlconf in middleware.

Для моего приложения, отменяя request.urlconf с промежуточным слоем был самым простым и наиболее элегантным решением. Вот фрагмент из промежуточного слоя:

# ... detect region first based on path, then session, and and maybe later IP address... 
# Then force the URLconf: 
if request.region == Region.EU: 
    request.urlconf = "mysite.regional_urls.eu_urls" 
else: 
    request.urlconf = "mysite.regional_urls.us_urls" 

я создал один новый URLconf в каждом регионе, но они сухи однострочечники:

urlpatterns = create_patterns_for_region(Region.EU) 

Эти ссылочные шаблон, который объединил оба URL, которые я хотел бы региональный с теми, что я хотел оставить «голый»:

from django.conf.urls import patterns, include, url 

    def create_patterns_for_region(region): 
     return patterns(
      '', 
      # First match regional. 
      url(r'^{}/'.format(region.short), include('mysite.regional_urls.regional_base_urls')), 
      # Non-regional pages. 
      url(r'', include('mysite.regional_urls.nonregional_base_urls')), 
      # Any regional URL is missing. 
      url(r'^{}/.*'.format(Region.REGION_PREFIX), error_views.Custom404.as_error_view()), 
      # Attempt to map any non-regional URL to region for backward compatibility. 
      url(r'.*', RegionRedirect.as_view()), 
     ) 

И, наконец, вид редирект для обратной совместимости:

class RegionRedirect(RedirectView): 
    """ Map paths without region to regional versions for backward compatibility. 
    """ 
    permanent = True 
    query_string = True 

    def get_redirect_url(self, *args, **kwargs): 
     self.url = "/" + self.request.region.short + self.request.path 
     return super(RegionRedirect, self).get_redirect_url(*args, **kwargs) 

Обязательно обновите кеширование, чтобы включить регион. ;)

1

Нет реального ответа, только два предложения:

  1. Вы можете не используют поддомены? Такая же идея с промежуточным ПО, но делает ее независимой от генерации URL.

  2. Django поддерживает вашу идею, но для языков, а не для регионов (docs here), возможно, вы можете приспособить это или, по крайней мере, посмотреть, как он решает вашу проблему.

+0

Thanks Remco. В основном я исключал субдомены, потому что они, как известно, плохо для SEO. Например, я хочу, чтобы доменный кредит для моего существующего сайта принес мне пользу в новых регионах. Мне придется посмотреть на документы на языке. –

+0

Да, что они делают для языков, именно то, что я пытаюсь сделать. Я могу сделать то же самое на стороне urlconf, используя https://docs.djangoproject.com/en/1.10/topics/http/urls/#including-other-urlconfs, однако я не вижу, как сделать реверсивную работу? –

+0

И даже включение не обеспечивает автоматическое поведение удаления кода языка с пути и не отправки его в качестве аргумента в представления. Также я хочу. –

 Смежные вопросы

  • Нет связанных вопросов^_^