Единственный учебник по программированию который я пока-что прочитал от корки до корки это "Язык программирования Python" хороший учебник. Многое мне дал. Остальные я использовал как справочники, и читал парочку первых страниц с описанием синтаксиса и основных особенностей.Да-да, это плохое качество, но когда времени нет на 1000 страниц теории, а надо сделать что-то ручками, и работающее, то Документация + http://stackoverflow.com/+ Блоги, и в атаку.
Так было и с Django.
И так, Writing Django widgets.Информации по этой теме мало, документация хреновая.Поделюсь 2-х дневным опытом.
Widget в переводе с забугорного знать как изобразить.
Что мы будем писать? Виджет календарика.Я погорячился со словом писать. Ну зачем писать то, что уже давно написано, причём сотни раз,умными трудолюбивыми людьми?
Пусть на другом языке, но написано.
Мы просто прикрутим Скриптик к нашей формочке.
Шаг 1
И так у нас есть простенькая формочка
class ContactForm(forms.Form):
subject = forms.CharField()
email = forms.EmailField()
Date = forms.DateField()
Дабы раскрыть архитектуру действия Вижетов, от календарика мы пока удалимся.
class My_widjet(forms.widgets.TextInput):
def render(self, name, value, attrs=None):
return """Простите Блог спот и highlight пытаются интерпритировать HTML Теги"""
Простите, Блог спот и highlight пытаются интерпритировать HTML Теги.Поэтому буду давать ссылки: Преведущий код. Да покажите мне такой пример 2 дня назад, я бы не заморачивался столько времени. И нервов бы сохранил. Это, только что, был наш с вами первый виджет. Теперь применим его (когда это возможно я всё-же код буду Пастить сюда)
class ContactForm(forms.Form):
subject = forms.CharField()
email = forms.EmailField()
Date = forms.DateField(widget = My_widjet)
Ну что, загружайте страничку с вашей формочкой, и "О чудо!" Наш виджет сработал Теперь это вовсе не поле для ввода даты, это ссылка на гугл.
Что от сюда надо вынести?
- Виджет целиком и полностью заменяет то к чему его применили. Заменяет он это методом render(он вызывается автоматически), точнее не самим методом а тем что он возвращает.
Но согласитесь, целый календарик в строку пихать это совсем по быдлокодерски. Поэтому любимый Django позаботился и дал нам класс Media в Виджете, с помощью него можно по человечески работать с таблицами стилей и яваскриптами . Слава богу, включение скриптов и стилей в Media хорошо продокументировано на официальном сайте. Но есть 1 костыль. Если вы прочти документацию, то увидели, что в последствии в виджете self.media(не люблю когда Питонеры попросту играются с регистром, вместо инициализации интуитивно понятных имён)
будут строки подключения файлов скриптов. Но работать эти строки будут уже в браузере. Я уже был в отчайнии, пока не догадался, что нужно сделать чтоб скрипты подключились. И так в медиа у нас лежит что-то типа
class Media:
js = (
"/src/js/unicode-letter.js",
)
а в render мы прописали что то типа
return "%s some code"%self.media
Таким фигом в браузере у нас<script type="text/javascript" src="/src/js/unicode-letter.js"></script>А что по Адресу скриптика? А 404 по адресу скриптика.
И отрубите мне копыта если это есть в официальной документации.
И почему там 404, и что делать? Всё просто. Ваш сайт это не html страница, это Джанго проект, и когда вы запрашиваете его о какой-то ссылке, он ищет её в файлике urls.py, и вызывает асоциирующуюся с ней функцию, которая в свою очередь возвращает, запросившему её, данные. Вот такой вот каламбур. Теперь когда нам известна суть проблемы мы может её решить.
Надо в наш фаил привязок добывить такую строку
('^src/([\x20-\x7E]*)/?$',views._catalog),
Для тех кому не понятно советую почитать про регулярные выражения, это очень полезно. Я в кратце поясню при вызове чего- начинающегося на src/... вызывается функция views._catalog с 2 аргументами, 1 - request. А второй это всё что после src/ в виде строки.
Далее создадим функцию _catalog в views
def _catalog(request,path):
path= ""
try:
f = open( os.path.join(os.path.dirname(__file__), 'src/').replace('\\','/')+path,'r')
path = f.read()
finally:
f.close()
return HttpResponse(path)
Да правильно, она считывает фаил по указаному пути( мы ведь уже не в браузере, и файловая система нам доступна)И ява скрипт будет работать.
Что от сюда надо вынести?
- Привязку пути для ваших скриптов к функции которая их возврашает
Тоесть надо подключить css и Js файлы, и выдать пару строк в ответе. Там около 15 файлов css.Можно было разоборатся, что надо, что не надо, и по подключать это как должно быть, но я устал, поэтому сделал так. Вот Класс Media для виджета календаря. Как видете, в нём я создал свою переменную my_css, благодоря этому мне не пришлось прописывать в словарик каждый css файлик.
Ну а теперь целиком весь виджет .
Меня не мало бесит, что приходится подставлять в строку (name,name,name,name) но я не придумал пока как это сделать по дугому. Думал сделать функцию типо этой
def N_times(times,what):
I=0;
T=tuple()
while I<=times:
I=I+1
T=T+(what,)
return T
Но это тоже не очень красиво. Придумаю отпишусь. Ну вот. Календарик есть. Ура. Мы разобрались как работают виджеты и сделали кадендарик который можно подключить в 1 строку к любому field-у.