Первый взгляд на Django

Поскольку Django был разработан в динамично развивающейся новостной среде, он призван сделать веб-разработку быстрее и легче. Вот неофициальный обзор того, как писать веб-приложения при помощи Django.

Цель данного документа: предоставить вам достаточное количество технической информации для понимания основ работы Django, но следует иметь ввиду, что этот обзор не предназначен быть учебником – хотя у нас есть хорошие новости! Когда вы будете готовы к созданию своего первого проекта, вы можете начать с учебного руководства или окунуться в море подробнейшей информации.

Проектирование модели

Хотя вы вполне можете обойтись без использования базы данных, Django предоставляет инструменты для описания формата БД.

Использование модели БД предлагает множество различных способов представления ваших данных – до сих пор, по прошествии двух лет, предлагаемый подход не вызывал никаких проблем с использованием БД.

from django.db import models

class Reporter(models.Model):
    full_name = models.CharField(max_length=70)

    # On Python 3: def __str__(self):
    def __unicode__(self):
        return self.full_name

class Article(models.Model):
    pub_date = models.DateField()
    headline = models.CharField(max_length=200)
    content = models.TextField()
    reporter = models.ForeignKey(Reporter)

    # On Python 3: def __str__(self):
    def __unicode__(self):
        return self.headline

Настройка базы данных

Теперь выполните команду для автоматического создания таблиц базы данных:

$ python manage.py syncdb

Команда syncdb отыщет все имеющиеся у вас модели и создаст на их основе соответствующие записи в БД.

Наслаждайтесь свободным API

Дело в том, что вам доступен развитый и бесплатный интерфейс для доступа к вашим данным. API создаётся на лету, без предварительной генерации кода:

# Import the models we created from our "news" app
>>> from news.models import Reporter, Article

# No reporters are in the system yet.
>>> Reporter.objects.all()
[]

# Create a new Reporter.
>>> r = Reporter(full_name='John Smith')

# Save the object into the database. You have to call save() explicitly.
>>> r.save()

# Now it has an ID.
>>> r.id
1

# Now the new reporter is in the database.
>>> Reporter.objects.all()
[<Reporter: John Smith>]

# Fields are represented as attributes on the Python object.
>>> r.full_name
'John Smith'

# Django provides a rich database lookup API.
>>> Reporter.objects.get(id=1)
<Reporter: John Smith>
>>> Reporter.objects.get(full_name__startswith='John')
<Reporter: John Smith>
>>> Reporter.objects.get(full_name__contains='mith')
<Reporter: John Smith>
>>> Reporter.objects.get(id=2)
Traceback (most recent call last):
    ...
DoesNotExist: Reporter matching query does not exist. Lookup parameters were {'id': 2}

# Create an article.
>>> from datetime import date
>>> a = Article(pub_date=date.today(), headline='Django is cool',
...     content='Yeah.', reporter=r)
>>> a.save()

# Now the article is in the database.
>>> Article.objects.all()
[<Article: Django is cool>]

# Article objects get API access to related Reporter objects.
>>> r = a.reporter
>>> r.full_name
'John Smith'

# And vice versa: Reporter objects get API access to Article objects.
>>> r.article_set.all()
[<Article: Django is cool>]

# The API follows relationships as far as you need, performing efficient
# JOINs for you behind the scenes.
# This finds all articles by a reporter whose name starts with "John".
>>> Article.objects.filter(reporter__full_name__startswith="John")
[<Article: Django is cool>]

# Change an object by altering its attributes and calling save().
>>> r.full_name = 'Billy Goat'
>>> r.save()

# Delete an object with delete().
>>> r.delete()

Динамический административный интерфейс: это не просто строительный материал – это готовый дом

Как только вы напишете модели, Django может автоматически создать профессиональный административный интерфейс, позволяющий авторизованным пользователям добавлять, удалять и изменять объекты. Для этого следует зарегистрировать свою модель:

# In models.py...

from django.db import models

class Article(models.Model):
    pub_date = models.DateField()
    headline = models.CharField(max_length=200)
    content = models.TextField()
    reporter = models.ForeignKey(Reporter)


# In admin.py in the same directory...

import models
from django.contrib import admin

admin.site.register(models.Article)

Задумка заключается в том, что редактировать разделы могут служащие или клиенты, или, может быть, только вы – и при этом вам не хотелось бы иметь дело с созданием бэкенд интерфейсов (backend interfaces) только лишь для управления контентом.

Обычным рабочим моментом при создании сайта на Django, является написание моделей и получение прав администратора для того, чтобы как можно скорее приступить к работе. Так ваши сотрудники (или клиенты) могут сразу же начать наполнение сайта данными, а вы параллельно продолжите подготавливать сайт для публикации.

Проектирование URL-адресов

Красивая, элегантная схема URL является важной составляющей высококачественного веб-приложения. Django поощряет создание красивых URL-адресов и не захламляет их подобно .php или же .asp.

Проектируя модель URL для своего приложения, вы создаёте модуль Python, называемый менеджером URL-ов. Оглавление вашего приложения представляет из себя простое соответствие между URL-адресом и вызываемой функцией на Python. URLconfs служит для связки URL-адреса и кода на Python.

Вот таким образом может выглядеть схема URL для классов Reporter/Article, представленных выше:

from django.conf.urls import patterns

urlpatterns = patterns('',
    (r'^articles/(\d{4})/$', 'news.views.year_archive'),
    (r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
    (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'),
)

Указанная схема URL содержит простые регулярные выражения для вызова соответствующей функции Python (соответствующего представления, “views”). Регулярные выражения используют кавычки для “захвата” значения из URL-адреса. Когда пользователь запрашивает страницу, Django проходит по всем шаблонам по порядку и останавливается на первом подходящем (если ни один из шаблонов не подошёл, Django вызовет исключение 404.) Это происходит за считанные доли секунды, поскольку регулярные выражения компилируются во время загрузки.

После того, как соответствующий шаблон найден, Django вызывает представление, которое является по сути простой функцией на Python. Каждое представление передаёт объект запроса – он содержит возвращаемые метаданные – и значение регулярного выражения.

К примеру, если пользователь запросил URL “/articles/2005/05/39323/”, Django должен вернуть функцию news.views.article_detail(request, '2005', '05', '39323').

Написание представлений

Каждое представление отвечает за выполнение одной из двух вещей: возвращение объекта HttpResponse, содержащего контент запрашиваемой страницы, или возбуждение исключения такого как Http404. Остальное зависит от вас.

Как правило, представление извлекает данные в соответствии с заданными параметрами, загружает шаблон и отображает этот шаблон вместе с полученными данными. Это пример представления year_archive, представленного выше:

from django.shortcuts import render_to_response

def year_archive(request, year):
    a_list = Article.objects.filter(pub_date__year=year)
    return render_to_response('news/year_archive.html', {'year': year, 'article_list': a_list})

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

Проектирование шаблонов

Код, представленный выше, возвращает шаблон news/year_archive.html.

Django включает пути поиска по шаблонам, что позволяет свести к минимуму избыточность html-кода. В настройках Django нужно указать список каталогов, откуда Django сможет загружать шаблоны. Это делается с помощью настройки TEMPLATE_DIRS. Если шаблон не будет найден в первом каталоге, Django проверит второй и все последующие.

Скажем, шаблон news/year_archive.html был найден. Вот как он может выглядеть:

{% extends "base.html" %}

{% block title %}Articles for {{ year }}{% endblock %}

{% block content %}
<h1>Articles for {{ year }}</h1>

{% for article in article_list %}
    <p>{{ article.headline }}</p>
    <p>By {{ article.reporter.full_name }}</p>
    <p>Published {{ article.pub_date|date:"F j, Y" }}</p>
{% endfor %}
{% endblock %}

Переменные всегда окружены двумя фигурными скобками. {{ article.headline }} означает “вывести переменную, хранящую заголовок статьи.” Хотя точка используется не только для доступа к атрибутам: с её помощью можно провести поиск в словаре, поиск индекса и вызов функции.

Примечательно, что {{ article.pub_date|date:"F j, Y" }} использует Unix-стиль “pipe” (символ вертикальной черты “|”). Это называется шаблонным фильтром и это хороший способ для фильтрации значений переменной. В примере фильтр даты приводит объект datetime к нужному виду (как нахождение функции даты в PHP).

Вы можете применить столько фильтров, сколько вам будет нужно. Вы можете писать собственные шаблонные фильтры. Вы можете писать собственные шаблонные теги, которые будут запускать код Python за кулисами.

Наконец, Django использует концепцию “наследования шаблонов”: это достигается путём включения базового шаблона {% extends "base.html" %}. И это значит, что первым будет загружен базовый шаблон, в котором определено множество различных блоков, которые в свою очередь также могут содержать в себе какие-то блоки. Короче говоря, это позволяет намного сократить количество html-шаблонов страниц: каждый новый шаблон должен включать уникальные элементы, присущие только ему.

Базовый шаблон “base.html”, включающий использование статики, может выглядеть следующим образом:

{% load staticfiles %}
<html>
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <img src="{% static "images/sitelogo.png" %}" alt="Logo" />
    {% block content %}{% endblock %}
</body>
</html>

Проще говоря, он определяет внешний вид сайта (подгружает логотип), а также оставляет место для заполнения блоков в дочерних шаблонах. Это позволяет свести редизайн всего сайта к изменению единственного файла – базового шаблона.

Также этот подход позволит вам создавать несколько версий сайта, использующих различные базовые шаблоны, в то время как дочерние шаблоны останутся неизменными. Создатели Django использовали этот подход для написания отдельного шаблона для мобильных устройств – просто создав новый базовый шаблон.

Обратите внимание на то, что вы можете не использовать язык шаблонов Django, если отдаёте предпочтение какому-то иному. Хотя язык шаблонов Django как нельзя лучше подходит при создании моделей Django, никто не заставляет вас использовать его. Если уж на то пошло, знайте, что вы даже вправе не пользоваться API баз данных Django. Вы можете использовать другой уровень абстракции базы данных, вы можете читать XML-файлы, вы можете читать файлы с диска, да и вообще делать всё, что угодно. Каждая часть Django – модели, представления, шаблоны – отделены друг от друга.

Это просто поверхностный взгляд

Это был только краткий обзор возможностей Django. Вот ещё несколько полезных особенностей, о которых следовало бы знать:

  • Система кэширования, интегрированная с memcached или другими типами кэшей.

  • Фреймворк syndication, позволяющий сделать создание RSS и Atom фидов таким же простым делом, как написание небольшого класса на Python.

  • Более изящный, генерируемый автоматически, административный интерфейс – этот обзор лишь едва коснулся его описания.

Следующими вашими шагами будут установка Django, чтение руководства и присоединение к англоязычному или к русскоязычному сообществам. Благодарим вас за проявленный интерес!