Автоматическая привязка URL к view
Раздел:
Programming /
Python
@
07.05.2008 |
Ключевые слова: python django url view
Автор: lomeolomeo
Источник: habrahabr
Я недавно "подсел" на Django и мне очень нравится этот фреймворк. Однако есть деталь, которая доставляет беспокойство. Это одновременное редактирование файла с моими views и файла urls.py
при создании нового view. Я понимаю, что это связано с тем, что URL
-ы и views вещи достаточно разные и для большей модульности лучше держать их раздельно, однако для небольших проектов было бы очень удобно иметь возможность править view и его настройки в одном месте.
Здесь я предлагаю такое решение, конечно же, завязанное на декораторах.
Итак, что в конечном итоге мы хотим получить? Допустим, нам нужно нарисовать новый view. Хочется дописать к этой функции декоратор with_url
:
@with_url(r`^my/cool/url/`)
def my_cool_view(request):
...
чтобы он сам всё подвязал, а нам не пришлось лазать руками в urls.py
.
Для этой цели служит небольшой модуль easyurls
из пакета, назовём его, djangoutils
:
urlpatterns = []
def with_url(url, context={}):
def decorator(fun):
global urlpatterns
urlpatterns.append((url, fun, context))
return fun
return decorator
def load_patterns(module_name):
from django.conf.urls.defaults import patterns
__import__(module_name)
return patterns(module_name, *urlpatterns)
Что он делает? Декоратор with_url
добавляет в глобальную переменную urlpatterns
привязку URL
к нашему view. А функция load_patterns
просто импортирует модуль views, чтобы все декораторы сработали, после чего возвращает заполненный urlpatterns
.
Используется это следующим образом. В файле urls.py
мы пишем
from djangoutils.easyurls import load_patterns
urlpatterns = load_patterns(`app.views`) + patterns(...)
где app.views
- модуль views нашего приложения. Больше мы в этот файл не заглядываем.
В модуль app.views
импортируем декоратор:
from djangoutils.easyurls import with_url
и теперь новые view можно писать примерно таким образом:
# простой пример
@with_url(r`^json/list/items/`)
@json_http
@in_list
def json_list_items(request, list):
...
# чуть сложнее :-)
@with_url(r`^$`)
@with_url(r`^start/`, {`is_root`: False})
def start(request, is_root=True):
...
Отступление: вообще, я активно пользуюсь декораторами для облегчения написания однотипного кода. Например, здесь декоратор json_http
преобразует результат функции в JSON строку и кидает её в response.
Недостаток предложенного решения, который я вижу сразу - это использование только одного load_patterns
в URL. Решить его можно, перенеся urlpatterns
из easyurls
в модуль views. Думаю, сделать это несложно, как дополнительное преимущество отпадёт необходимость в использовании load_patterns
и будет достаточно стандартного include
. Как недостаток - придётся выписывать urlpatterns = []
в каждом модуле views, который мы вяжем таким образом. Возможно и не придётся, если python может из одного модуля создавать глобальную переменную в другом и проверять есть ли она там уже.
Это не велосипед, кстати?
Спасибо тем, кто дочитал до этого места :-)
Это интересно:
Распечатать статью
Вернуться в раздел:
Programming /
Python
Реклама: