Простая установка Django 4.2: краткое руководство
Оглавление
- Установка
- Создание приложения Django
- Определение моделей
- Управление данными
- Presenting Your Posts
- Summary
Цель этой статьи - как можно быстрее начать использовать Django для создания веб-приложения и начать путь к готовому к производству приложению. В качестве демонстрации мы создадим простой блог для нашей компании под названием Foo.
Установка
При условии, что у вас настроен Python с помощью pip, установка проста. В результате будет установлен Django вместе с полезной командой, которая поможет быстро запустить проект.
pip install django
Следующая команда создает каталог проекта foo/
и формирует базовую структуру проекта и некоторые начальные файлы.
django-admin startproject foo
Давайте быстро пройдемся по каждому из созданных нами файлов:
manage.py
- это утилита командной строки, которую предоставляет Django. Она поставляется с рядом команд, которые поддерживаются из коробки, некоторые из них мы рассмотрим позже. Некоторые приложения Django, которые вы сможете установить позже, добавят команды, доступные через эту утилиту, и в конечном итоге вы сможете добавлять свои собственные по мере необходимости.
foo/settings.py
- это начальный пример файла настроек Django, который должен содержать всю конфигурацию вашего приложения. Если вы посмотрите на него, то увидите значения по умолчанию, которые настраивают ваше приложение для работы в локальной среде разработки.
foo/urls.py
- это местоположение по умолчанию для конфигурации URL. По сути, это предоставляет Django правила маршрутизации запросов, которые получает ваше приложение.
foo/wsgi.py
- это место, где находится собственно WSGI-приложение. При работе с Django в производстве необходимо использовать сервер типа uwsgi или green unicorn, серверы которых взаимодействуют с приложением, находящимся в этом файле. Теперь, когда мы создали проект, давайте попробуем его запустить. Чтобы запустить встроенный сервер разработки, выполните команду:
./manage.py runserver
Вы должны увидеть вывод, указывающий на используемые настройки и на то, где доступен сервер. Обратите внимание, что по умолчанию сервер доступен по адресу http://127.0.0.1:8000. Если перейти по этому адресу, то загрузится страница по умолчанию, сообщающая об успешной установке Django. Как видно из страницы, единственная причина, по которой вы видите эту страницу, заключается в том, что конфигурация по умолчанию, представленная в файле settings.py, имеет значение DEBUG = True
. В противном случае при попытке перейти на эту страницу вы получили бы сообщение 404, поскольку конфигурация URL в urls.py не направляет этот путь ни к чему в вашем приложении.
Учет зависимостей
Прежде чем двигаться дальше, давайте создадим файл requirements.txt в базовом каталоге проекта, чтобы отслеживать все зависимости, которые мы устанавливаем с помощью pip. Пока мы установили только Django, поэтому наш файл requirements.txt будет выглядеть примерно так:
django==4.2
Создание приложения Django
Терминология немного запутанная, но проект Django состоит из нескольких приложений (не путать с WSGI-приложением). Чтобы начать работу над блогом, давайте создадим приложение, которое будет обеспечивать функциональность блога в нашем Django-проекте:
./manage.py startapp blog
Команда startapp, как и startproject, создает для вас шаблонное приложение. Еще раз посмотрим на созданные нами файлы:
blog/__init__.py
- это стандартный python __init__.py для превращения каталога в Python-модуль.
blog/admin.py
- это файл для регистрации ваших моделей в Django Admin.
blog/apps.py
содержит объект конфигурации Django Application. Он сообщает Django подробную информацию о вашем приложении.
blog/migrations/
- это папка для миграций вашей базы данных. В основном она управляется ORM Django. Как создавать миграции и применять их, мы рассмотрим позже.
blog/models.py
- это место, куда следует помещать модели, использующие Django ORM. Это представляет собой интерфейс с вашим внутренним хранилищем данных.
blog/tests.py
предоставляет место для размещения тестов для тестирования вашего приложения.
blog/views.py
предоставляет определения для представлений ваших приложений. Именно здесь находится наша логика обработки запросов.
Регистрация приложения
Для того чтобы проект Django узнал о вашем приложении, вам необходимо зарегистрировать его, добавив в INSTALLED_APPS
в settings.py
. Теперь ваша INSTALLED_APPS
должна выглядеть следующим образом:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
]
Определение Models
Теперь, когда наше приложение зарегистрировано, давайте определим модель данных для нашего блога. Допустим, мы хотим, чтобы в нашем блоге отображался список записей, помеченных различными темами, и чтобы люди, зарегистрировавшиеся в нашем блоге, могли комментировать эти записи.
Мы определяем эти модели в blog/models.py
:
from django.conf import settings
from django.db import models
class Topic(models.Model):
slug = models.SlugField(max_length=50, unique=True)
name = models.CharField(max_length=50)
class Post(models.Model):
slug = models.SlugField(max_length=50, unique=True)
title = models.CharField(max_length=50)
body = models.TextField()
published_on = models.DateTimeField(null=True, blank=True)
topics = models.ManyToManyField('Topic', related_name='posts')
class Comment(models.Model):
post = models.ForeignKey(
'Post', on_delete=models.CASCADE, related_name='comments'
)
user = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE,
related_name='comments'
)
body = models.TextField()
commented_on = models.DateTimeField(auto_now_add=True)
Здесь много деталей, но в основном мы определили объекты, описанные выше, а также связь между этими объектами и пользовательской моделью Django, используемой при аутентификации. Определив модели, мы хотим сгенерировать миграции базы данных, чтобы создать таблицы базы данных.
Для генерации миграций можно воспользоваться командой makemigrations
Django:
./manage.py makemigrations
При выполнении этой команды вы увидите краткую информацию о произведенных изменениях и имена созданных файлов миграций. В данном случае это должен быть только один файл, который будет являться начальной миграцией для нашего блог-приложения. Открыв blog/migrations/0001_initial.py
, вы увидите, какие шаги, по мнению Django, необходимо предпринять для изменения текущего состояния базы данных на новое заданное состояние. Чтобы применить эти изменения, мы используем команду migrate:
./manage.py migrate
Поскольку мы впервые выполняем команду migrate, будет запущен и ряд других миграций. Эти миграции происходят из некоторых встроенных приложений Django, которые включают поддержку:
- Модель пользователя аутентификации и прав доступа
- Модели отслеживания администраторов
- Фреймворк ContentTypes
- Сессии
Если посмотреть на базовый каталог проекта, то можно заметить новый файл: db.sqlite3. По умолчанию Django использует SQLite3 в качестве внутреннего хранилища данных, которое записывает файл базы данных в текущий рабочий каталог.
Управление данными
Теперь, когда мы определили модель данных и создали таблицы базы данных, необходимо найти способ управления данными в нашей базе. Админ Django - это невероятно быстрый способ создания интерфейса для управления данными, хранящимися в ваших моделях. В разделе blog/admin.py
мы можем быстро зарегистрировать наши модели, чтобы сделать интерфейс управления доступным в админке Django:
from django.contrib import admin
from .models import Comment, Post, Topic
admin.site.register(Comment)
admin.site.register(Post)
admin.site.register(Topic)
Теперь, зарегистрировав наши модели, мы можем перейти к админке Django, которая по умолчанию (если смотреть на foo/urls.py
) размещена по адресу /admin
, а на нашем локальном сервере доступна по адресу http://localhost:8000/admin/. Однако при попытке доступа к админке происходит перенаправление на экран входа в систему. В нашей системе еще не создан пользователь, поэтому мы не можем войти в систему, поэтому давайте создадим нового пользователя с правами администратора.
Опять же, в Django для этого есть команда:
./manage.py createsuperuser
Вам будет предложено ввести имя пользователя, e-mail и пароль (дважды). После создания нового суперпользователя (admin) можно войти в систему и изучить интерфейс. Вы увидите, что, не меняя ничего, есть раздел Authentication and Authorization, который можно использовать для управления системой аутентификации и разрешений Django, в которой есть Users and Groups. Далее вы найдете раздел для нашего блог-приложения, который поддерживает интерфейс для создания, редактирования и удаления тем, постов и комментариев.
Презентация своих сообщений
Теперь, когда мы можем создавать и хранить данные, мы хотим создать страницу, которая предоставляет список всех наших сообщений, и страницу, которая отображает одно сообщение, позволяя пользователям комментировать его. Для каждой страницы необходимо написать представление (для обработки запроса), шаблон (для отображения html) и конфигурацию url (для маршрутизации запроса).
Виды
Для начала определим два представления в blog/views.py
:
from django.shortcuts import redirect, render, reverse
from django.views.generic import DetailView, ListView
from .forms import CommentForm
from .models import Post
class PostListView(ListView):
model = Post
class PostDetailView(DetailView):
model = Post
def post(self, request, slug=None):
form = CommentForm(data=request.POST)
if form.is_valid():
form.save()
return redirect(
reverse('blog:post_detail', kwargs={'slug': slug})
)
return self.get(request, slug=slug)
def get_context_data(self, **kwargs):
ctx = super(PostDetailView, self).get_context_data(**kwargs)
ctx['form'] = CommentForm(
initial={
'post': self.object,
'user': self.request.user
}
)
return ctx
Django предоставляет несколько общих представлений, которые обрабатывают большую часть необходимой нам логики. Представление ListView
позволяет указать модель и получить список всех объектов в этой таблице для использования в вашем шаблоне. DetailView
позволяет указать модель и получить один объект из таблицы, заданный уникальным идентификатором в конфигурации url. В данном случае мы будем использовать slug, определенный для модели Post.
Поскольку мы также хотим поддерживать комментирование, мы переопределяем метод get_context_data, чтобы добавить CommentForm
, определенный в blogs/forms.py, в контекст, который DetailView будет передавать шаблонизатору для отрисовки шаблона. Нам также необходимо добавить метод post к DetailView
, который использует CommentForm
для создания комментариев:
from django import forms
from .models import Comment
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('post', 'user', 'body')
widgets = {
'post': forms.HiddenInput(),
'user': forms.HiddenInput()
}
Templates
Для того, чтобы реально вывести HTML, мы хотим использовать шаблоны. По умолчанию встроенные представления Django будут искать шаблон списка постов по адресу blog/templates/blog/post_list.html
и шаблон деталей постов по адресу blog/templates/blog/post_detail.html
. Чтобы избежать дублирования кода, мы создадим базовый шаблон и расширим его, чтобы создать шаблоны для двух наших страниц.
Сначала введите blog/templates/blog/base.html
:
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}Foo Blog{% endblock title %}</title>
</head>
</head>
<body>
{% block content %}
{% endblock content %}
</body>
</html>
Теперь мы можем создать HTML для представления списка в blog/templates/blog/post_list.html
:
{% extends "blog/base.html" %}
{% block content %}
<h1>Foo Blog</h1>
<div>
{% for post in object_list %}
<div>==========================================================</div>
<div>Posted on {{ post.published_on }}</div>
<div><h3>{{ post.title }}</h3></div>
<div>{{ post.snippet }}...<a href="{% url "blog:post_detail" slug=post.slug %}">continue reading.</a></div>
<div>==========================================================</div>
<br/>
{% endfor %}
</div>
{% endblock content %}
А HTML для детального представления в blog/templates/blog/post_detail.html
имеет вид:
{% extends "blog/base.html" %}
{% block content %}
<h3>{{ object.title }}</h3>
<h4>Topics</h4>
<ul>
{% for topic in object.topics.all %}
<li>{{ topic.name }}</li>
{% endfor %}
</ul>
<div>Posted on {{ object.published_on }}</div>
<br/>
<div>{{ object.body }}</div>
<br/>
<div>
<h4>Comments</h4>
{% for comment in object.comments.all %}
<div>---------------------------------------------------</div>
<div>{{ comment.body }}</div>
<div>Commented on {{ comment.commented_on }}</div>
<div>---------------------------------------------------</div>
{% endfor %}
</div>
{% if user.is_authenticated %}
<div>
<h4>Leave a Comment</h4>
<form method="post">
{% csrf_token %}
<div>{{ form.post }}</div>
<div>{{ form.user }}</div>
<div>{{ form.body }}</div>
<button>Submit</button>
</form>
</div>
{% endif %}
<br/>
<div><a href="{% url "blog:post_list" %}"><< Back to Post List</a></div>
{% endblock content %}
Конфигурация URL
Наконец, мы хотим направить запросы к нашим представлениям, чтобы сделать их доступными в нашем веб-приложении. Поскольку мы можем захотеть, чтобы этот блог был только отдельной частью нашего проекта (и веб-приложения), мы можем сохранить все хорошо разделенным и модульным, определив конфигурацию url блога в приложении блога и включив эту конфигурацию в конфигурацию url проекта. Начнем с того, что создадим blog/urls.py
:
from django.urls import path
from .views import PostDetailView, PostListView
app_name = 'blog'
urlpatterns = [
path('', PostListView.as_view(), name='post_list'),
path('/', PostDetailView.as_view(), name='post_detail'),
]
Затем измените foo/urls.py
:
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls', namespace='blog')),
]
Теперь наш блог доступен по адресу http://localhost:8000/blog/, а каждая запись будет доступна по адресу http://localhost:8000/blog/<slug >/.
Итоги
При минимальных затратах времени и усилий мы реализовали простейший блог, который хоть и не имеет стилистики, но вполне функционален. Используя встроенный в Django интерфейс администратора, мы можем управлять всеми данными: темами, постами и комментариями. Данные сохраняются через определения моделей с помощью ORM Django. Наконец, мы настраиваем некоторые маршруты, представления и шаблоны, чтобы сделать наши сообщения общедоступными в нашем веб-приложении.
Что дальше?
Созданное нами приложение для ведения блога является функциональным, но базовым. В идеале мы хотели бы добавить в наши шаблоны дизайн/стилистику, чтобы представить наши записи в более красивом виде. Мы также хотели бы иметь редактор в нашем административном инструменте с возможностью применения форматирования, которое будет транслироваться в html для отображения записи. Возможно, нам понадобится возможность фильтрации по темам или поиска конкретных сообщений. Каждое из этих дополнений легко реализуемо либо с помощью сторонних расширений для Django, либо в рамках самого фреймворка. Наконец, блог необходимо будет развернуть в производственной среде, для чего потребуется поддержка производственных настроек в приложении, решение для хостинга, механизмы развертывания, производственные веб-серверы и серверы приложений для размещения приложения, а также виртуальный или физический сервер для размещения всего этого программного обеспечения.
Вернуться на верх