• en
  • Язык: ru

Django: первый взгляд

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

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

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

Хотя вы можете использовать Django без базы данных, он поставляется с объектно-реляционным отображением (ORM), в котором вы описываете структуру вашей базы данных в коде Python.

Синтаксис модели данных предлагает множество способов представления ваших данных. Это позволяет решать задачи по использованию различных БД. Вот быстрый пример:

mysite/news/models.py
from django.db import models

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

    def __str__(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_delete=models.CASCADE)

    def __str__(self):
        return self.headline

Создание таблиц БД

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

$ python manage.py makemigrations
$ python manage.py migrate
...\> py manage.py makemigrations
...\> py manage.py migrate

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

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

Благодаря этому у вас есть бесплатный и мощный Python API для доступа к вашим данным. API создается на лету, генерация кода не требуется:

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

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

# 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()
<QuerySet [<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.

# 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()
<QuerySet [<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()
<QuerySet [<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')
<QuerySet [<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 может автоматически создать профессиональный, готовый к работе административный интерфейс — веб-сайт, который позволяет аутентифицированным пользователям добавлять, изменять и удалять объекты. Достаточно только зарегистрировать вашу модель на сайте администратора:

mysite/news/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, on_delete=models.CASCADE)
mysite/news/admin.py
from django.contrib import admin

from . import models

admin.site.register(models.Article)

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

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

Проектирование URL

Чистая и красивая схема URL — важная деталь в высококачественном веб-приложении. Django поощряет красивый дизайн URL-адресов и не вносит ничего лишнего в URL-адреса (например, .php или .asp.

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

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

mysite/news/urls.py
from django.urls import path

from . import views

urlpatterns = [
    path('articles/<int:year>/', views.year_archive),
    path('articles/<int:year>/<int:month>/', views.month_archive),
    path('articles/<int:year>/<int:month>/<int:pk>/', views.article_detail),
]

Приведенный выше код сопоставляет пути URL с функциями Python («views»). Строки пути используют теги параметров для «захвата» значений из URL. Когда пользователь запрашивает страницу, Django пробегает каждый путь по порядку и останавливается на первом, который соответствует запрошенному URL. (Если ни один из них не совпадает, Django вызывает специальное представление 404.) Это невероятно быстро, потому что пути компилируются в регулярные выражения во время загрузки.

Когда один из шаблонов URL совпадает, Django вызывает заданное представление (напоминаем, что это обычная функцией Python). Каждое представление получает объект запроса, который содержит метаданные запроса, и значения, захваченные в шаблоне URL.

Например, если пользователь запросил URL-адрес «/article/2005/05/39323/», Django вызовет функцию news.views.article_detail (request, year=2005, month=5, pk=39323).

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

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

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

mysite/news/views.py
from django.shortcuts import render

from .models import Article

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

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

Создание шаблонов

Приведенный выше код загружает шаблон news/year_archive.html.

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

Допустим, шаблон news/year_archive.html был найден. Вот как это может выглядеть:

mysite/news/templates/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" }} использует «pipe» в стиле Unix (символ «|»). Это называется фильтром шаблона, т.е. способ фильтрации значения переменной. В этом случае фильтр даты форматирует объект даты и времени Python в заданном формате (как в функции даты в PHP).

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

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

Вот как может выглядеть шаблон «base.html», включая использование статических файлов:

mysite/templates/base.html
{% load static %}
<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 или любым другим бэкендом.
  • Фреймворк синдикации делает создание каналов RSS или Atom таким же простым, как написание небольшого класса Python.
  • Более привлекательные автоматически сгенерированные функции администратора - этот обзор едва коснулся его описания.

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

Вернуться на верх