Django: первый взгляд¶
Because Django was developed in a fast-paced newsroom environment, it was designed to make common web development tasks fast and easy. Here’s an informal overview of how to write a database-driven web app with Django.
Цель этого документа — дать вам достаточно технических подробностей, чтобы понять, как работает Django. Но это не учебник или справочник, хотя есть здесь и они. Когда вы будете готовы начать проект, вы можете начать с учебника или погрузиться в подробную документацию.
Проектирование модели¶
Хотя вы можете использовать Django без базы данных, он поставляется с объектно-реляционным отображением (ORM), в котором вы описываете структуру вашей базы данных в коде Python.
Синтаксис модели данных предлагает множество способов представления ваших данных. Это позволяет решать задачи по использованию различных БД. Вот быстрый пример:
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 может автоматически создать профессиональный, готовый к работе административный интерфейс — веб-сайт, который позволяет аутентифицированным пользователям добавлять, изменять и удалять объекты. Единственный необходимый шаг - зарегистрировать вашу модель на сайте администратора:
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)
from django.contrib import admin
from . import models
admin.site.register(models.Article)
Идея такого решения заключается в том, что ваш сайт редактируется персоналом, или клиентом, или, может быть, только вами — и нет необходимости иметь дело с созданием внутренних интерфейсов только для управления контентом.
Один из типичных рабочих процессов при создании приложений Django — это создание моделей и максимально быстрый запуск сайта администрирования, чтобы сотрудники (или клиенты) могли начинать вводить данные. А в это время вы можете продолжать работу над публичной частью проекта.
Проектирование URL¶
A clean, elegant URL scheme is an important detail in a high-quality web
application. Django encourages beautiful URL design and doesn’t put any cruft
in URLs, like .php
or .asp
.
Для проектирования URL-адресов приложения, вы должны создать модуль Python URLconf. Оглавление вашего приложения – это простое сопоставление между шаблонами URL и функциями обратного вызова Python. URLconfs также служат для отделения URL-адресов от кода Python.
Вот как может выглядеть URLconf для примера Reporter
/Article
, приведенного выше:
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
:
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
был найден. Вот как это может выглядеть:
{% 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», включая использование статических файлов:
{% 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, чтение учебника и присоединение к сообществу. Спасибо за ваш интерес!