<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>

<channel>
	<title>джангонавт.ru</title>
	<atom:link href="http://djangonaut.ru/feed/" rel="self" type="application/rss+xml" />
	<link>http://djangonaut.ru</link>
	<description>django tips &#38; tricks</description>
	<pubDate>Wed, 20 Jan 2010 10:49:25 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>create_object и дополнительные поля создаваемого объекта</title>
		<link>http://djangonaut.ru/2009/08/30/create_object-with-additional-fields/</link>
		<comments>http://djangonaut.ru/2009/08/30/create_object-with-additional-fields/#comments</comments>
		<pubDate>Sat, 29 Aug 2009 13:49:13 +0000</pubDate>
		<dc:creator>finn</dc:creator>
		
		<category><![CDATA[Основная лента]]></category>

		<category><![CDATA[generic views]]></category>

		<guid isPermaLink="false">http://djangonaut.ru/?p=47</guid>
		<description><![CDATA[Среди убойных возможностей django хочется отметить generic views.  Поначалу я их не заметил и практически никак не использовал, но после прочтения этой статьи присмотрелся внимательней и проникся.  Сейчас иногда получается, что они напрямую или через функции-обертки реализуют почти весь view-слой сайта.
Одной из проблем, с которой я столкнулся при использовании generic views — это [...]]]></description>
			<content:encoded><![CDATA[<p>Среди убойных возможностей django хочется отметить generic views.  Поначалу я их не заметил и практически никак не использовал, но после прочтения <a href="http://www.b-list.org/weblog/2006/nov/16/django-tips-get-most-out-generic-views/">этой статьи</a> присмотрелся внимательней и проникся.  Сейчас иногда получается, что они напрямую или через функции-обертки реализуют почти весь view-слой сайта.</p>
<p>Одной из проблем, с которой я столкнулся при использовании generic views — это вопрос о том, как добавить в объект, создаваемый через create_object, дополнительные данные.  Например, при создании новой статьи хочется автоматом прописывать залогиненного пользователя, который её написал.  Поскольку create_object создает и использует ModelForm внутри себя, то способ передачи request.user в эту форму не совсем очевиден.</p>
<p>А способ-то довольно прост — достаточно описать ModelForm внутри функции-обертки над create_object.  Если в этом описании переопределить метод save(), то request будет в пределах видимости.</p>
<p>Вот наша модель (models.py):</p>
<pre><code class="python">from django.contrib.auth.models import User
from django.db import models

class Article(models.Model):
    title = models.CharField(max_lentg=100)
    content = models.TextField()
    author = models.ForeignKey(User)</code></pre>
<p>Вот форма (forms.py):</p>
<pre><code class="python">from django import forms
from articles.models import Article

class ArticleForm(forms.ModelForm):
    class Meta:
        model = Article
        fields = ('title', 'content', )</code></pre>
<p>А вот та самая функция обертка:</p>
<pre><code class="python">from django.views.generic.create_update import create_object
from articles.forms import ArticleForm

def create_article(request):
    class AddArticleForm(ArticleForm):
        def save(self):
            article = super(AddArticleForm, self).save(commit=False)
            article.author = request.user
            article.save()
            return article
    return create_object(request, form_class=AddArticleForm, login_required=True)</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://djangonaut.ru/2009/08/30/create_object-with-additional-fields/feed/</wfw:commentRss>
		</item>
		<item>
		<title>direct_to_template вместо render_to_response</title>
		<link>http://djangonaut.ru/2009/08/23/direct_to_template-instead-of-render_to_response/</link>
		<comments>http://djangonaut.ru/2009/08/23/direct_to_template-instead-of-render_to_response/#comments</comments>
		<pubDate>Sat, 22 Aug 2009 13:01:40 +0000</pubDate>
		<dc:creator>finn</dc:creator>
		
		<category><![CDATA[Основная лента]]></category>

		<category><![CDATA[generic views]]></category>

		<guid isPermaLink="false">http://djangonaut.ru/?p=43</guid>
		<description><![CDATA[Везде и всюду для загрузки и рендеринга шаблона для последующей отдачи браузеру рекомендуется использовать функцию render_to_response.  Однако, если её использовать правильно, а не так, как написано в туториале, то помимо самой функции приходится импортировать еще и RequestContext, и явно передавать его:
from django.shortcuts import render_to_response
from django.template import RequestContext

def my_view(request):
    return render_to_response('my_template.html',
  [...]]]></description>
			<content:encoded><![CDATA[<p>Везде и всюду для загрузки и рендеринга шаблона для последующей отдачи браузеру рекомендуется использовать функцию render_to_response.  Однако, если её использовать правильно, а не так, как <a href="http://docs.djangoproject.com/en/dev/intro/tutorial03/#a-shortcut-render-to-response">написано в туториале</a>, то помимо самой функции приходится импортировать еще и RequestContext, и явно передавать его:</p>
<pre><code class="python">from django.shortcuts import render_to_response
from django.template import RequestContext

def my_view(request):
    return render_to_response('my_template.html',
                              {'object_list': SomeModel.objects.all()},
                              context_instance=RequestContext(request))</code></pre>
<p>То есть по факту получается, что это не такой уж и shortcut.  Такой многословный код приводит к тому, что многие программисты делают собственные версии render_to_response, которые одним из параметров принимают request.  А особо продвинутые джангонавты даже <a href="http://www.djangosnippets.org/snippets/821/">мудрят с декораторами</a>.</p>
<p>Однако в django уже есть функция, которая фактически делает то же самое.  Смотрите сами:</p>
<pre><code class="python">from django.views.generic.simple import direct_to_template

def my_view(request):
    return direct_to_template(request, 'my_template.html',
                              {'object_list': SomeModel.objects.all()})</code></pre>
<p>Все generic views правильно работают с RequestContext и direct_to_template тут не исключение.</p>
]]></content:encoded>
			<wfw:commentRss>http://djangonaut.ru/2009/08/23/direct_to_template-instead-of-render_to_response/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Admin actions в качестве views</title>
		<link>http://djangonaut.ru/2009/05/03/admin-actions-as-views/</link>
		<comments>http://djangonaut.ru/2009/05/03/admin-actions-as-views/#comments</comments>
		<pubDate>Sun, 03 May 2009 12:16:04 +0000</pubDate>
		<dc:creator>finn</dc:creator>
		
		<category><![CDATA[Основная лента]]></category>

		<category><![CDATA[actions]]></category>

		<category><![CDATA[admin]]></category>

		<guid isPermaLink="false">http://djangonaut.ru/?p=28</guid>
		<description><![CDATA[Долгое время в джанговской админке не было встроенной поддержки для массовых действий над записями.  К примеру как только не приходилось извращаться для хотя бы чуть более удобного удаления объектов.
В версии 1.1 джангонавтам привалило счастье - групповые операции. Удаление кучки объектов теперь есть прямо из коробки. При этом, как обычно это бывает в django, использовать [...]]]></description>
			<content:encoded><![CDATA[<p>Долгое время в джанговской админке не было встроенной поддержки для массовых действий над записями.  К примеру как только не приходилось извращаться для хотя бы <a href="http://webnewage.org/2009/4/15/revisited-chut-bolee-byistroe-udalenie-obektov-v-adminke/">чуть более удобного удаления объектов</a>.</p>
<p>В версии 1.1 джангонавтам привалило счастье - <a href="http://docs.djangoproject.com/en/dev/ref/contrib/admin/actions/">групповые операции</a>. Удаление кучки объектов теперь есть прямо из коробки. При этом, как обычно это бывает в django, использовать новый механизм легко и приятно - написание простенького action укладывается в две-три строчки.   Больше того, action может не только как-то молча обрабатывать группу объектов, но и возвращать HttpResponse, в котором пользователь может проделать дополнительные действия.</p>
<p>Документация в качестве примера <a href="http://docs.djangoproject.com/en/dev/ref/contrib/admin/actions/#actions-that-provide-intermediate-pages">предлагает</a> возвращать HttpResponseRedirect и передавать список обрабатываемых объектов в виде GET-параметра полноценной view для последующей самостоятельной работы. Однако, ничего не мешает использовать наш action в качестве view-функции.</p>
<p>Допустим у нас есть магазин, в котором товары разбиты по категориям:</p>
<pre><code class="python">class Category(models.Model):
    name = models.CharField(u'Наименование', max_length=100)

    def __unicode__(self):
        return self.name

class Product(models.Model):
    category = models.ForeignKey(Category, verbose_name=u'Категория')
    name = models.CharField(u'Наименование', max_length=100)
    price = models.DecimalField(u'Цена', max_digits=15, decimal_places=2)
</code></pre>
<p>Время от времени пользователю хочется перенести пачку товаров из одной категории в другую (к примеру разбили «Молоко» на «Молоко настоящее»/«Молочные продукты» и надо раскидать товары согласно указаниям санэпидстанции и угрызениям своей совести).  Чтобы человек не мучался, выставляя каждому такому товару новую категорию, мы и напишем нехитрый action.</p>
<pre><code class="python">class CategoryForm(forms.Form):
    category = forms.ModelChoiceField(queryset=Category.objects.all())

class ProductAdmin(admin.ModelAdmin):
    list_display = ('name', 'price', 'category',)
    actions = ['set_category_action']

    def set_category_action(self, request, queryset):
        if 'do_action' in request.POST:
            form = CategoryForm(request.POST)
            if form.is_valid():
                queryset.update(category=form.cleaned_data['category'])
                # Ничего не возвращаем, это вернет нас на список товаров
                return
        else:
            form = CategoryForm()
        return render_to_response(
            'admin/shop/set_category.html',
            {'title': u'Укажите категорию, в которую надо переместить товары',
             'objects': queryset,
             'form': form},
            context_instance=RequestContext(request))
    set_category_action.short_description = u'Переместить в категорию'
</code></pre>
<p>Поддерживающий это дело set_category.html прост. Через hidden-поля <strong>action</strong> и <strong>_selected_action</strong> мы заставляем админку опять вызвать наш action, но на этот раз в POST попадают две дополнительные переменные: <strong>do_action</strong> (флажок, что мы пришли из формы) и <strong>category</strong> (та категория, которую надо назначить).</p>
<pre><code class="django">{% extends "admin/base_site.html" %}

{% block content %}

    &lt;form action="" method="post"&gt;

        &lt;input type="hidden" name="action" value="set_category_action"&gt;
        &lt;input type="hidden" name="do_action" value="yes"&gt;

        &lt;div&gt;
            {{ form.category }}
            &lt;input type="submit" class="default" style="float: none" value="Переместить"&gt;
            {{ form.category.errors }}
        &lt;/div&gt;

        &lt;h2&gt;Товары для перемещения&lt;/h2&gt;

        &lt;ul&gt;
            {% for object in objects %}
                &lt;li&gt;
                    &lt;a href="{{ object.pk }}/"&gt;{{ object.name }}&lt;/a&gt; - {{ object.category }}
                    &lt;input type="hidden" name="_selected_action" value="{{ object.pk }}"&gt;
                &lt;/li&gt;
            {% endfor %}
        &lt;/ul&gt;

    &lt;/form&gt;

{% endblock %}
</code></pre>
<p><img class="aligncenter size-full wp-image-31" title="Admin action view" src="http://djangonaut.ru/wp-content/uploads/2009/05/admin_actions_as_views.gif" alt="Admin action view" width="629" height="239" /></p>
<p>Вот таким простым образом мы избавились от необходимости писать лишний view, самостоятельно выдергивать в нем список объектов, придумывать url и делать редирект на change list.</p>
]]></content:encoded>
			<wfw:commentRss>http://djangonaut.ru/2009/05/03/admin-actions-as-views/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Использование sorl.thumbnail без template tags</title>
		<link>http://djangonaut.ru/2009/05/02/usign-sorl-thumbnail-without-template-tags/</link>
		<comments>http://djangonaut.ru/2009/05/02/usign-sorl-thumbnail-without-template-tags/#comments</comments>
		<pubDate>Sat, 02 May 2009 11:23:17 +0000</pubDate>
		<dc:creator>finn</dc:creator>
		
		<category><![CDATA[Основная лента]]></category>

		<category><![CDATA[admin]]></category>

		<category><![CDATA[thumbnail]]></category>

		<guid isPermaLink="false">http://djangonaut.ru/?p=4</guid>
		<description><![CDATA[Практически в каждом django-проекте рано или поздно встает вопрос о генерировании превьюшек для картинок.  Одним из наиболее простых и удобных решений для этого является sorl.thumbnail.  Это приложение позволяет генерировать превьюшки либо прямо в шаблоне через тег {% thumbnail %}, либо используя в моделях специальное поле ImageWithThumbnailsField.  В подавляющем большинстве случаев этого достаточно, но иногда возникает [...]]]></description>
			<content:encoded><![CDATA[<p>Практически в каждом django-проекте рано или поздно встает вопрос о генерировании превьюшек для картинок.  Одним из наиболее простых и удобных решений для этого является <a title="sorl.thumbnail" href="http://code.google.com/p/sorl-thumbnail/">sorl.thumbnail</a>.  Это приложение позволяет генерировать превьюшки либо прямо в шаблоне через тег <nobr>{% thumbnail %}</nobr>, либо используя в моделях специальное поле ImageWithThumbnailsField.  В подавляющем большинстве случаев этого достаточно, но иногда возникает необходимость получить превьюшку в python-коде прямо по месту, без переделывания моделей.</p>
<p>К примеру может захотеться видеть совсем маленькие, нигде больше не используемые превьюшки в списке объектов в админке. Делается это на удивление просто.</p>
<pre><code class="python">class PatternAdmin(admin.ModelAdmin):
    list_display = ('icon', '__unicode__',)
    list_display_links = ('__unicode__',)

    def icon(self, obj):
        from sorl.thumbnail.main import DjangoThumbnail
        thumbnail = DjangoThumbnail(obj.photo, (60, 60))
        return u'&lt;img src="%s" border="0" alt="" width="%s" height="%s" /&gt;' % \
                            (thumbnail.absolute_url,
                             thumbnail.width(), thumbnail.height())
    icon.short_description = u'Фото'
    icon.allow_tags = True</code>
</pre>
<p>В результате получаем вот такой список объектов:</p>
<p><img class="aligncenter size-full wp-image-16" title="sorl.thumbnail в django admin" src="http://djangonaut.ru/wp-content/uploads/2009/05/sorl_thumbnail_admin.gif" alt="sorl.thumbnail в django admin" width="404" height="296" /></p>
]]></content:encoded>
			<wfw:commentRss>http://djangonaut.ru/2009/05/02/usign-sorl-thumbnail-without-template-tags/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>

