джангонавт.ru

Archive for the ‘generic views’ tag

create_object и дополнительные поля создаваемого объекта

without comments

Среди убойных возможностей django хочется отметить generic views. Поначалу я их не заметил и практически никак не использовал, но после прочтения этой статьи присмотрелся внимательней и проникся. Сейчас иногда получается, что они напрямую или через функции-обертки реализуют почти весь view-слой сайта.

Одной из проблем, с которой я столкнулся при использовании generic views — это вопрос о том, как добавить в объект, создаваемый через create_object, дополнительные данные. Например, при создании новой статьи хочется автоматом прописывать залогиненного пользователя, который её написал. Поскольку create_object создает и использует ModelForm внутри себя, то способ передачи request.user в эту форму не совсем очевиден.

А способ-то довольно прост — достаточно описать ModelForm внутри функции-обертки над create_object. Если в этом описании переопределить метод save(), то request будет в пределах видимости.

Вот наша модель (models.py):

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)

Вот форма (forms.py):

from django import forms
from articles.models import Article

class ArticleForm(forms.ModelForm):
    class Meta:
        model = Article
        fields = ('title', 'content', )

А вот та самая функция обертка:

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)

Written by finn

Август 30th, 2009 at 12:49 дп

direct_to_template вместо render_to_response

with 6 comments

Везде и всюду для загрузки и рендеринга шаблона для последующей отдачи браузеру рекомендуется использовать функцию 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',
                              {'object_list': SomeModel.objects.all()},
                              context_instance=RequestContext(request))

То есть по факту получается, что это не такой уж и shortcut. Такой многословный код приводит к тому, что многие программисты делают собственные версии render_to_response, которые одним из параметров принимают request. А особо продвинутые джангонавты даже мудрят с декораторами.

Однако в django уже есть функция, которая фактически делает то же самое. Смотрите сами:

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()})

Все generic views правильно работают с RequestContext и direct_to_template тут не исключение.

Written by finn

Август 23rd, 2009 at 12:01 дп