Невозможно динамическое изменение urlpattern при изменении базы данных - PullRequest
0 голосов
/ 07 января 2012

Я хочу обновить соответствие шаблона URL моего продукта при изменении базы данных, поэтому я использую в urls.py:

main_cagetory_url=Product_category.objects.get_all_product_category_url()
main_cagetory_url_string = '(?:' + '|'.join(main_cagetory_url) + ')'

product_url=Product.objects.get_all_product_url()
product_url_string = '(?:' + '|'.join(product_url) + ')'

menu_url=Menu.objects.get_all_menu_url()
menu_url_string = '(?:' + '|'.join(menu_url) + ')'

urlpatterns = patterns('',
                       (r'^$',menu_page),
                       (r'^home_vi$',home_vi),
                       (r'^home_en$',home_en),
                       (r'^'+menu_url_string+'$',menu_page),
                       (r'^'+main_cagetory_url_string+'$',list_product),
                       (r'^'+product_url_string+'$',product_detail),
                       (r'^search_result$',search_result),
                       (r'^admin/', include(admin.site.urls)),)

Все в порядке, когда я занимаюсь разработкой на моем компьютере.Но когда я загрузил свой проект на хостинг.Каждый раз, когда я добавляю новую Product_category или Product.Django не может понять это изменение и выдает ошибку 404, когда я нажимаю на новую категорию Product_category или новый продукт.

Как я могу исправить эту ошибку?

Ответы [ 2 ]

2 голосов
/ 07 января 2012

Вероятно, лучше отобразить ваши URL так:

url(r'^category/(?P<category_name>\w+)/$', 'views.list_products'),

и предоставьте им функцию вида, подобную этой:

def list_product(request, category_name=None):
    if category_name:
    # check if a category exists
    # list product from the category
    else:
    # do something else
1 голос
/ 07 января 2012

Это началось как комментарий, но я подумал, что постараюсь не создавать последовательный комментарий.

Причина, по которой это работает в режиме разработки, заключается в том, что сервер dev автоматически перезагружает любые файлы (например, urls.py), которыеменять.Этого не происходит (и вы не хотите, чтобы это произошло) на рабочем сервере.У меня никогда не было необходимости делать это самому, поэтому я внимательно изучаю код и документы, чтобы увидеть, где могут быть зацепки.

Что ж, потратив на это около 45 минут, мой ответ кажется ... Вы не можете сделать это, по крайней мере, нелегко.Обратите внимание, что все номера строк ниже взяты из Django 1.3.1.

Django инициализирует ваши URL-адреса из модуля, указанного в вашем файле настроек, как ROOT_URLCONF, обычно urls.Эта инициализация несколько дорогая, и Django старается изо всех сил кэшировать все, что может.

В BaseHandler.get_response() (django/core/handles/base.py строка 83) urlresolvers.set_urlconf() вызывается с использованием модулей urls, названных в settings.ROOT_URLCONF.По сути, это глобальные, зашитые знания о том, где находится конфигурация URL.Из-за кэширования он инициализирует ваши URL только один раз на поток .Это означает, что каждый поток на веб-сервере, который обрабатывает ваши запросы Django, должен быть предупрежден о необходимости сбрасывать и инициализировать его URL-адреса каждый раз, когда происходит изменение базы данных, и это само по себе усложняется.

Anальтернативным методом будет либо создание супер-шаблона , который вызывает представление, которое, в свою очередь, выполняет вызов БД.Другой подход состоит в том, чтобы обработать это в классе middleware , где вы проверяете на ошибку 404, проверяете, является ли шаблон одной из ваших категорий, а затем проверяете там БД.Я делал это в прошлом, и это не так плохо, как кажется.Посмотрите на код django/contrib/flatpages для простой реализации этого подхода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...