Сегодня продолжим знакомство с Django и наконец то рассмотрим базовый кирпич, а именно приложение(application) на примере создания приложения contact, для отсылки каких-то сообщений администрации. Причем напомню что этот цикл практический, в нем я почти не рассказываю почему, лишь говорю как, потому что я все равно не напишу лучше чем в документации: http://docs.djangoproject.com/en/dev/
Разработка каждого приложения начинается с команды:
manage.py startapp contact
Где contact - названия приложения.
В результате будет создана папка contact со следующими файлами:
- models.py
- views.py
- __init___.py
И сразу же перейдем к файлу models.py, в котором разместим модель базы данных для сохранения сообщений:
from django.db import models
from django.contrib.auth.models import User
class Contact(models.Model):
user = models.ForeignKey(User, blank=True, null=True)
email = models.EmailField(blank=True, null=True)
text = models.TextField()
is_answered = models.BooleanField(default=False)
pub_date = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
return '%s - %s' % (self.email, self.pub_date)
Как видим модель представляет собой описание каждого поля, и в первой строчке создаем внешний ключ, что будет связан с таблицей пользователя, а также указываем что поле не обязательное.
Второе поле для емайла и в нем в параметрах указываем, что его также можно оставить пустым.
3-е поле тектовое для непосредтсвенно сообщения.
4-е булевое поле, которое по умолчанию будет всегда False.
И последнее поле, в котором будем дата публикации сообщения, в параметрах которого указываем что это поле будет автоматически заполняться текущей датой и временем при создании записи.
Теперь если мы добавим наше приложение в INSTALLED_APP в настройках, то при исполнении команды:
manage.py syncdb
данная таблица будет создана.
Во всех веб-приложения всегда нужна работа с формами, и в Django она реализована очень удачно, и большинстве случаев нам даже не нужно их расписывать, а мы лишь укажем что форма должна сама строиться на основе модели. Для этого в файл models.py добавим такие строчки:
from django.forms import ModelForm
class ContactForm(ModelForm):
class Meta:
model = Contact
fields = ['email','text']
Теперь можно построить отображение, что покажет нашу форму.
В файл views.py вставим такой код:
from django.views.generic.simple import direct_to_template
from django.http import HttpResponseRedirect
from contact.models import ContactForm
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
if request.user.is_authenticated():
instance.user = request.user
instance.email = request.user.email
instance.save()
return HttpResponseRedirect('/')
else:
form = ContactForm()
if request.user.is_authenticated():
del(form.fields['email'])
return direct_to_template(request, 'contact.html', {
'form': form,
})
Как видим отображение, является простой функцией, что принимает входящим параметр request и возвращает response.
В нашей функции вначале проверяем - этот запрос POST или нет. Если нет, то переменную form присваеваем обьект на основе нашей формы ContactForm():
form = ContactForm()
Также проверяем юзера и если он уже зарегистрирован, то ему же не нужно показывать поле с емайлом, мы его можем и сами заполнить, поэтому можем то поле удалить с формы:
del(form.fields['email'])
А дальше отображаем шаблон contact.html(который размещается в папке templates) передав ему нашу форму. Файл contact.html может выглядеть так:
{% extends 'base.html' %}
{% block title %} Contact {% endblock %}
{% block content %}
{% endblock %}
Как видим в шаблоне все нам знакомое, лишь уникальное то что отображается форма такой строчкой:
{{ form.as_ul }}
А поскольку мы помним что мы переменной form присвоили обьект формы, то стоит обьяснить что указав после точки as_ul по сути Django вызовет функцию:
form.as_ul()
Еще можна было форму отобразить как таблицу {{ form }}, или как абзацы: {{ form.as_p }}
Но в нашем views.py мы не рассмотрели участок когда запрос у нас POST:
form = ContactForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
if request.user.is_authenticated():
instance.user = request.user
instance.email = request.user.email
instance.save()
return HttpResponseRedirect('/')
Итак сначал создаем обьект формы и под начальными значениями берем POST параметры, что пришли вместе с формой. Дальше проверяем форму на валидность, и если все нормально то строчкой, создамем поле таблицы contact со значениями из формы:
instance = form.save(commit=False)
Причем говорим, что пока что не нужно записывать поле в базу, потому что если юзер уже зарегистрирован, то мы можем сами заполнить поле с юзером и емайлом:
instance.user = request.user
instance.email = request.user.email
Дальше сохраняем поле в базу:
instance.save()
И пересылаем юзера на главную страницу:
return HttpResponseRedirect('/')
Теперь наше отображение готовое и мы можем привязать URL к нему. Для этого добавим такие строчки в файл urls.py:
urlpatterns = patterns('',
(r'^contact/$', 'contact.views.contact'),
)
Где мы говорим что когда юзер зайдет по адресу /contact/, то нужно использовать функцию contact из файла contact/views.py
Теперь юзеры могут легко сохранять нам сообщения, но мы их не можем читать, и чтобы это исправить добавим в папку contact файл admin.py:
from django.contrib import admin
from contact.models import Contact
class ContactAdmin(admin.ModelAdmin):
list_display = ['__unicode__', 'pub_date', 'is_answered']
ordering = ['-is_answered', '-pub_date']
admin.site.register(Contact, ContactAdmin)
Этим мы добавим возможность просматривать все сообщения в админке, при этом мы указываем что при отображение полей отображать поля пречисленные в list_display, причем вместо полей можно указывать функции из моделей, как в примере с функцией __unicode__.
А также мы указываем сортировку в которой говорим что сначала нужно показывать не отвеченные коментарии, и дальше сортировать по мере даты публикации.
На этом эту часть можно считать законченной, здесь конечно есть много чего дополнить, но это уже в следующей части.
Все исходники этого приложения можна глянуть в git репозитарию сайта http://gread.org.ua/ по адресу http://github.com/presidentua/gread/
Содержание:
Часть 1 - http://tutamc.com/node/183
Часть 2 - http://tutamc.com/node/186
Часть 3 - http://tutamc.com/node/194
Часть 4 - http://tutamc.com/node/199
