четверг, 8 декабря 2011 г.

Кеширование отдельных запросов

На днях возникла необходимость сделать кеширование некоторых сложных запросов. Просто по таймауту, без инвалидации. Делать общее кеширование на сайте нельзя, потому что шаблоны генерируются сложно, в зависимости от многих данных.

среда, 27 апреля 2011 г.

Shortcuts в Django 1.3

Америку не открываю, но думаю что многим будет полезно.

1. Рендеринг:

from django.shortcuts import render

def page(request):
    retval = 'value'
    return render(request,'page.html',{'var':retval})


2. Редирект

from django.shortcuts import redirect

def page(request):
    return redirect('url_name') #Если у ссылки есть название в urls.py
    ...
    или
    ...
    return redirect('/page/') #Если у ссылки нет названия в urls.py


2. Получить объект или вернуть 404 страницу

from django.shortcuts import get_object_or_404
from django.contrib.auth.models import User

def page(request):
    get_object_or_404(User,id=1) #Если объекта нету, возвращает 404 страницу. Если есть, идет дальше
    ...
    return ...

суббота, 10 июля 2010 г.

Django и AJAX

Итак, задача:

1. Ajax должен работать так же просто и эффективно как Django
2. Количество кода для средних задач должно быть настолько минимальным, насколько это возможно
3. Подключить Ajax-функцию должно быть не сложнее чем написать простейшую python-функцию

Решение:

Уж не знаю кто как решает эту задачу, но я уверен что почти каждый django-разработчик сталкивался с ней хотя бы раз в жизни. Вот и я однажды задумался по этому поводу. И почему-то мне захотелось использовать в решении этой задачи RPC. Настоящий такой, красивый и простой RPC...

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

Судя по всему, проект еще достаточно зеленый, однако пользоваться библиотеками уже вполне можно и нужно. Кстати, о птичках. На сайте есть две библиотеки:

1. Dajaxice:
Связующее ядро dajaxproject. Ее основная цель заключается в банальном асинхронном взаимодействии в рамках кода на стороне сервера Django и вашего JavaScript-кода.

Работает оно примерно следующим образом:




2. Dajax:
Мощный инструмент для легкой и супер-быстрой разработки асинхронной логики в web-приложений с использованием Python и почти отсутствием JavaScript-кода.


Схема работы:



Итак, инструкция по применению:

1. Качаем стабильную версию Dajaxice и Dajax. Не забываем, что ядром является именно Dajaxice, поэтому оно всему и голова.
2. Распаковываем оба архива и в каждом поочередно делаем так:


$ sydo python setup.py install


3. В Вашем settings.py ищем INSTALLED_APPS и добавляем в самый низ две строки:


INSTALLED_APPS = ( 
'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions', 
'django.contrib.sites',
...
 'dajaxice', 
 'dajax', 
...
 )


4. Смотрим, чтобы TEMPLATE_LOADERS выглядели примерно так. Если нужно, редактируем:


TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
    'django.template.loaders.eggs.Loader',
)


5. Добавляем новую переменную DAJAXICE_MEDIA_PREFIX в settings.py:


DAJAXICE_MEDIA_PREFIX="dajaxice"


6. В urls.py в самом конце добавляем новую строку:


urlpatterns = patterns('',
    ...
    (r'^%s/' % settings.DAJAXICE_MEDIA_PREFIX, include('dajaxice.urls')),
    )

7. Если необходимо, добавляем импорт в urls.py:


from django.conf import settings

8. Выбираем приложение, в котором нам нужно создать RPC-вызовы и создаем там новый модуль ajax.py. Я например, предпочитаю такие вещи хранить отдельно, поэтому создал отдельное приложение jsrpc.

9. Собственно пишем первый метод, который обработает наш AJAX-запрос:


# -*- coding: utf-8 -*-
from django.utils import simplejson 
from dajaxice.core import dajaxice_functions 

def primer(request,message):
    return_message=u'Полученное сообщение: {0}'.format(message)
    return simplejson.dumps({'message':return_message})


10. В settings.py делаем так, чтобы новый метод был виден для AJAX-запросов:


DAJAXICE_FUNCTIONS = (
        'jsrpc.ajax.primer',
         )

11. В шаблоне, в пределах тега пишем так:


{% load dajaxice_templatetags %}{% dajaxice_js_import %}

12. Создаем кнопку чтобы проверить работоспособность:


<input onclick="Dajaxice.jsrpc.primer('primer_callback',{'message':'Хэллоу Уорлд!'});" type="button" value="Push Me!" />


Перевожу... В onclick мы должны указать какую из подключенных функций мы будем юзать. После Dajaxice нужно указать только приложение и метод в модуле ajax.py. В нашем примере получается Dajaxice.jsrpc.primer. 

Далее, в качестве первого параметра указываем callback, в который возвратить данные, чтобы потом разгребать средствами JavaScript. В нашем случае - primer_callback, его мы создадим позже.

Ну и как же без набора параметров... Если мы что-то хотим передать серверу, пишем точно также как обычно передаем из сервера в шаблоны. В данном случае, мы просто передаем строку на сервер. А сервер нам должен вернуть ее же. Не забываем объявить параметр message в параметрах метода, иначе ничего не получится.

13. Напишем callback:


<script type="text/javascript">
function primer_callback(data){
    if(data!=Dajaxice.EXCEPTION){
        alert(data.message);
    }else{
        alert('Error');
    }
}
</script>



Обратите внимание, что мы получаем "свыше" уже сериализованные данные, что, безусловно, очень удобно.

14. Должно работать:


До сих пор мы пользовались только первой библиотекой - ядром Dajaxice. Что же нам могут предложить во второй библиотеке, если итак все уже шоколадно?


Скажу от себя, что предлагают нам не совсем "правильные" вещи, хотя и достаточно удобные.


Изначально Django проектировался так, чтобы полностью исключить любую возможную логику в шаблонах. И наоборот, серверная логика не должна знать вообще о существовании шаблонов, об их устройстве и структуре HTML. Если нам захотелось поменять верстку в шаблонах, это никак не должно отражаться на серверном коде. И это правильно. То что описано ниже, напрочь противоречит всем правилам! Однако, как бы то ни было, считаю своим долгом рассказать о том "неправильном" подходе, который предлагает библиотека Dajax, а дальше - выбирайте сами.


Так как мы уже подключили практически все необходимое, остается лишь одна маленькая деталь. В скачанном и распакованном архиве django-dajax-0.8.4 идем в каталог src/ и выбираем нужную библиотеку, в зависимости от того, какой JavaScript-фреймворк мы используем в проекте. Нам доступны:


1. Dojo
2. JQuery
3. Mootools
4. Prototype


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


1. Копируем jquery.dajax.core.js в каталог MEDIA_ROOT/js/.
2. В шаблоне, в пределах тега <head></head> подключаем эту самую библиотеку:


<script type="text/javascript" src="{{ MEDIA_URL }}/js/jquery.dajax.core.js" charset="utf-8"></script>


3. Подключили. Теперь создаем кнопочку и поле для вывода, чтобы почувствовать разницу в использовании:



<input type='button' value='Push Me!' onclick="Dajaxice.jsrpc.primer2('Dajax.process');" id='knopka'>
<div id='testarea'></div>


4. Создаем метод в уже созданном модуле


# -*- coding: utf-8 -*-
from django.utils import simplejson
from dajaxice.core import dajaxice_functions
from dajax.core import Dajax
...

def primer2(request):
    dajax = Dajax()
    dajax.assign('#knopka','value',u'Нажато')
    dajax.assign('#testarea','innerHTML',u'Бла-бла-бла')
    return dajax.json()


Обратите внимание, что значения для HTML-элементов Вы указываете именно на сервере. Это то о чем я писал выше. Неудобно, но зато JavaScript всего одна строка, да и то в пределах onclick. Решайте сами, использовать или нет.


5. Ну и подключаем метод в settings.py:


DAJAXICE_FUNCTIONS = (
        ...
        'jsrpc.ajax.primer2',
         )





6. Вот собственно и все. Теперь все должно работать:





пятница, 9 июля 2010 г.

Recaptcha и Django

Однажды мне понадобилось прикрутить каптчу к регистрации, к комментариям и еще в пару мест в одном из проектов. Из всех каптч мне по определению больше всего нравится сервис ReCaptcha. Не буду описывать плюсы и минусы, а просто поделюсь готовым решением.

1. Для начала качаем само приложение
2. Распаковываем (tar -xf django-recaptcha.tar.gz) в корне вашего проекта
3. В settings.py добавляем две константы:

RECAPTCHA_PUBLIC_KEY='бла-бла-бла'
RECAPTCHA_PRIVATE_KEY='бла-бла-бла'

4. Заменяем "бла-бла-бла" на то, что выдали в http://www.google.com/recaptcha
5. Далее, если мы хотим защитить от роботов форму регистрации, создаем в приложении для аккаунтов модуль forms.py и пишем туда примерно следующее:

from my_project.recaptcha.fields import ReCaptchaField
from django.contrib.auth.forms import UserCreationForm
...
class UserCreationFormExtended(UserCreationForm): 
    recaptcha = ReCaptchaField(label=u'Символы с картинки')

    def __init__(self, *args, **kwargs): 
        super(UserCreationFormExtended, self).__init__(*args, **kwargs) 
        self.fields['email'].required = True

    class Meta:
        model = User
...

6. Ну, и, собственно, в views.py, который рендерит регистрационную форму, пишем примерно так:

from forms import UserCreationFormExtended
...
form = UserCreationFormExtended()
return {'form': form}

Это все.

P.S. Приложение django-recaptcha, которое Вы скачали по ссылке выше, не имеет никакого отношения к любым другим. Это приложение было отчасти переписано, отчасти написано с нуля мной и имеет только русскоязычную версию. Если будет необходимо, сделаем multilanguage-вариант.

среда, 7 июля 2010 г.

Новое русскоязычное сообщество Django

Новое русскоязычное сообщество Django: проблемы с Django и python, идеи, наработки, нюансы, код, приложения, для гуру и новичков - и _всегда_ помогаем друг-другу:

1. Группа - http://groups.google.com/group/django_ru
#Обсуждения, мозговые штурмы, взаимопомощь и ответы на любые вопросы

2. Блог - http://django-ru.blogspot.com/
#Интересные и полезные статьи и уроки на русском

3. Исходные тексты - http://code.google.com/p/django-ru/
#Тут можно скачать полезные вещи для Django

Популярные вопросы и обсуждения:

- Django и ajax
- Формы в Django
- Модели в Django
- Редактирование базы данных в Django
- Изменение базы данных в Django
- Работа с email в Django
- Django CMS
- Django и шаблоны
- Django и админка
- Хостинг для Django
- Django и nginx
- Django и apache