Django - это веб фреймворк написанный на Python с помощью которого можно быстро создавать веб приложения и сайты. В этой статье будет рассмотрена установка Django 3 с созданием простого приложения на Linux или Windows.
Что такое фреймворк?
Если упрощать понятие фреймворка можно сказать, что это просто набор готовых компонентов (классов, модулей, пакетов), которые разработчик может включать в программу тем самым экономя свое время. Один из таких компонентов может быть модуль аутентификации так как он требуется практически во всех приложениях, а за счет использования фреймворка вы можете не задумываться о всех деталях логики, а просто импортировать его.
Веб-фреймворки, на примере Django, можно грубо сравнить с CMS (Bitrix, Wordpress). Создавая сайт на CMS вы сразу получаете инструменты с которыми могут работать конечные пользователи. Это могут быть: системы оплаты, компоненты для ведения клиентов, корзина и т.д. Иногда они хороши и их достаточно, но если понадобится расширение функционала - это может вызвать сложности.
Во фреймворках изначально нет никаких инструментов для конечного пользователя, но их можно построить с помощью существующего функционала и сделать такими как вам хочется. Django как раз и отличается тем, что вы можете сделать это быстро и понятно для других разработчиков.
Социальную сеть, так же как и примеры ниже, построить на CMS практически невозможно.
Что написано на Django?
В список проектов, которые полностью или частично используют Django, включают: Disqus, Instagram, Spotify, YouTube, DropBox, Mozzila, Pinterst.
Этот список описан в большинстве статей, но проверить наверняка практически не возможно.
Установка Django
Для установки фреймворка у вас уже должен быть Python версии > 3.6. Проверить это можно в любом терминале так:
python3 -V
В зависимости от ОС интерпретатор python может писаться без и с версией (как на примерах выше). В Linux в чаще используется 'python3', а в Windows просто 'python'. Это правило касается и pip.
Pip - это менеджер пакетов. Проще говоря через него удобнее устанавливать и удалять пакеты. В Windows он уже должен быть, а для Linux устанавливается отдельно:
sudo apt install python3-pip
Каждый проект Django рекомендуется создавать в отдельной виртуальной среде. Виртуальная среда помогает нам следить за версиями пакетов, которые мы будем устанавливать для определенного проекта. Если это первый проект, то его можно создать и вне виртуальной среды, но если планируется перенос на хостинг - это крайне рекомендуется.
Перейдите в директорию где вы планируете создать свой проект и выполните следующую команду для создания виртуального окружения:
python3 -m venv env
Активируем окружение:
# cmd
env\Scripts\activate.bat
# powershell
env\Scripts\Activate.ps1
# bash
source env/bin/activate
То что мы находимся в рамках виртуального окружения говорит следующая часть:
В рамках этого окружения мы выполняем установку Django:
pip3 install django
Создание проекта
Создание проекта с именем app можно выполнить следующей командой:
django-admin startproject app
Моя структура папок имеет следующий вид:
Сам проект (директория) app имеет следующую структуру:
- manage.py - файл, с помощью которого мы можем управлять нашим проектом. С помощью него можно запустить проект, создание и выполнить миграцию в базу данных, создать суперпользователя и много другое;
- wsgi.py - это файл, который используется при переносе проекта на хостинг. С помощью него часть задач выполняет Django (динамические файлы), а часть задач такой сервер как Apache/Nginx (статические файлы, например картинки);
- urls.py - файл описывающий отношения между url, которые будет открывать пользователь и функциями, которые этот запрос будут обрабатывать. urls.py часто называют файлом маршрутизации;
- settings.py - описывает настройки проекта. Это может быть база данных, часовой пояс, место где будут храниться статические файлы и многое другое;
- __init__ - идентифицирует приложение как модуль;
- asgi.py - замена wsgi.py, так как он считается устаревшим. Это новинка в Django 3 для поддержки асинхронного программирования.
Для проверки работы Django мы можем сразу его запустить. Запуск осуществляется через manage.py:
python3 manage.py runserver
# другие варианты запуска - зависят от ОС
./manage.py runserver
python manage.py runserver
.\manage.py runserver
О запущенном сервере говорит окно под номером 1. Если открыть адрес в браузере 'http://127.0.0.1:8000/', то мы увидим окно под номером 2:
Использование виртуальных сред venv и virtualenv для создания окружения Python
Создание приложения
Приложение - это функциональная часть Django. В нем мы будем описывать логику той программы, которую захотим создать. Для примера мы хотим создать приложение, которое будет генерировать случайное число - его мы назовем 'generator'. Приложения создаются следующей командой:
python3 manage.py startapp generator
В директории с проектом появится папка 'generator' со следующим содержимым:
- vews.py - в этом файле описывается основная функциональная часть приложения. Когда посетитель сайта откроет какую-то страницу его запрос будет сравнен с тем, что находится в urls.py, а затем уже будет вызвана одна из функций во views.py;
- test.py - здесь создаются методы, которые могут протестировать работу приложения;
- models.py - в этой части, в основном, прописываются таблицы для базы данных. По умолчанию используется база sqllite, но можно подключить и другие;
- migrations - папка в которой будут храниться запросы для базы данных. Запросы создаются автоматически, но после определенной команды;
- __init__ - говорит, что папка - это модуль;
- apps.py - настройки приложения;
- admin.py - в Django есть панель администрирования, которую можно открыть по адресу http://127.0.0.1/admin/ . В этом файле можно связать приложение с этой панелью тем самым добавив возможность редактирования каких-то данных для себя или конечных пользователей. Например это может быть возможность редактирования записей в блоге.
По умолчанию приложение не связано с проектом. Для его связи нужно отредактировать файл 'settings.py' в папке 'app'.
Нужно добавить строку следующего формата 'папка приложения.файл конфигурации приложения.имя класса'. По умолчанию файл конфигурации называется apps, а название класса можно увидеть внутри него.
'generator.apps.GeneratorConfig'
В файле settings.py, в списке 'INSTALLED_APPS' уже содержаться приложения. Они нужны для самого Django. Если вы будете устанавливать дополнительные приложения для Django, их тоже нужно будет добавлять в этот список.
Откроем файл views.py и добавим следующие строки:
import random
from django.http import HttpResponse
# Create your views here.
def generate(request):
number = str(random.randint(1,10))
return HttpResponse(f'<h1>{number}</h1>')
Где:
- request - это аргумент функции который хранит метаданные запроса пользователя. Называть этот аргумент именно так не обязательно, но это обще принятая практика;
- HttpResponse - это базовая функция, которая вернет пользователю указанную информацию. На практике, обычно, используются другие функции и классы, но для простой демонстрации он подходит лучше всего.
Данную функцию нужно привязать к определенному адресу в urls.py:
from generator.views import generate
...
path('', generate)
Где:
- Мы импортируем функцию, которую создали в приложении generator;
- Мы связываем путь '', который является корневым (т.е. http://127.0.0.1/) с определенным адресом. Теперь, каждый раз открывая главную страницу, будет срабатывать эта функция.
В urls.py так же можно видеть ссылку на панель администрирования - пользователя для нее создадим позже.
Запустим сервер:
python3 manage.py runserver
Обновляя страницу мы будем видеть разные числа:
Создание шаблона
Шаблоны в Django (templates), упрощая, это html страницы. Когда пользователь открывает какую-то страницу, то Django может взять шаблон и добавить в него ваши переменные и функции, а затем вернуть пользователю. Чаще всего эти значения называются тэгами (template tags). По умолчанию эти шаблоны создаются для каждого приложения отдельно.
Что бы использовать шаблоны нам нужно создать путь 'templates/generator/' в папке приложения 'generator'. В этой директории нужно создать файл 'index.html'
В файл index.html поместите следующий текст:
<p>Случайная цифра: {{ num }} </p>
<p>{% now "SHORT_DATETIME_FORMAT" %}</p>
Где:
- {{ num }} - это переменная, которую мы будем передавать в этот шаблон;
- {% now "SHORT_DATETIME_FORMAT" %} - это функция, которая возвращает время в коротком формате.
Обычно переменные используются через двойные скобки, а функции и методы через скобку со знаком %.
В файле views.py изменим код указав шаблон и переменную из примера выше:
def generate(request):
number = str(random.randint(1,10))
return render(request, 'generator/index.html', {'num': number})
Где:
- render - это функция, которая объединит шаблон с контекстом (добавит переменные);
- request - это запрос пользователя;
- generator/index.html - шаблон, который мы создавали на предыдущем шаге;
- {num: number} - словарь, который содержит данные для шаблона.
Запустим сервер:
python3 manage.py runserver
Похожих функций и методов много. Например можно использовать в шаблонах циклы, форматировать даты, проверять прошел ли пользователь аутентификацию, а так же создавать свои и многое другое. Все из них можно найти по запросам 'теги шаблонов Django' или 'template tags Django'.
Так же можно создавать базовые шаблоны, с элементами которые используются на всем сайте и использовать конструкции типа {% block %} {% include %} {% extend %}, которые будут дополнять его.
Создание модели
Модели - это объекты с помощью которых можно создать таблицу в базе данных, а так же получить из нее данные. Такие объекты создаются в файле models.py для каждого приложения отдельно.
Сделаем так, что бы случайные числа сохранялись вместе с тем временем в какое они были созданы. Для этого запишите в файл model.py следующий код:
class Numbers(models.Model):
integer = models.IntegerField(blank=False)
date = models.DateTimeField(auto_now=True)
Где:
- Numbers - это имя класса и название таблицы (не полное), которое будет создано в базе данных;
- models.Model - имя класса от которого мы наследуемся. Каждая модель должна наследоваться от него;
- IntegerField / DateTimeField - для каждой колонки в базе данных должен быть указан тип данных, который будет в нем хранится. В нашем случае это число и дата со временем. Таких типов данных много;
- blank - обозначает может ли поле быть пустым;
- auto_now - говорит, что дата будет фиксироваться и вноситься в строку таблицы автоматически.
После создания модели нам нужно выполнить две команды:
# Сформируем SQL запрос
python3 manage.py makemigrations
# Выполним SQL запрос на базе данных
python3 manage.py migrate
Далее нам нужно изменить файл views.py добавив следующую логику:
# Импортируем нашу модель
from .models import Numbers
def generate(request):
# Получаем все объекты модели
all_numbers = Numbers.objects.all()
current_number = str(random.randint(1,10))
# Добавляем в таблицу(базу) запись с новым числом (дата создается автоматически)
Numbers.objects.create(integer=current_number)
# Отправляем пользователю шаблон с новым числом и теми, которые были созданы ранее
return render(request, 'generator/index.html', {'num': current_number, 'all_numbers': all_numbers})
Любая модель в Django возвращает объект типа 'QuerySet' (как в случае с переменной 'all_numbers' выше). Это тип немного похож на обычный словарь, а значения, которые хранит переменная 'all_numbers' будут иметь примерно такую структуру:
all_numbers = [
{'integer': 5, 'date':'1990-15-06'},
{'integer': 6, 'date':'1990-15-08'},
]
Для того что бы эти значения корректно отобразились в шаблоне - мы должны изменить файл 'generator/templates/index.html' используя следующие значения:
<p>Случайная цифра: {{ num }} </p>
<ul>
<!-- Простой цикл -->
{% for number in all_numbers %}
<!-- Использование текущего значения цикла -->
<li>Номер: {{ number.integer }} Дата: {{ number.date }}</li>
<!-- Завершения цикла -->
{% endfor %}
</ul>
Как и на примере выше, в тегах Django часто используется конструкция, где вы объявляете начало и конец блока в отличие от обычного Python, где это делается с помощью отступов.
Запустим проект:
python3 manage.py runserver
После нескольких обновлений страницы мы увидим следующий результат:
Работа с панелью администрирования
Django уже содержит небольшую панель администрирования, но мы так же можем ее расширить используя существующие классы и создавая новые.
Добавим возможность, с помощью которой мы сможем изменить одно из чисел сгенерированных ранее, добавить новое или удалить старое.
Первое что нужно сделать - это завести пользователя следующим путем:
python3 manage.py createsuperuser
Запустив сервер вы сможете зайти в панель администрирования по следующему пути:
http://127.0.0.1/admin
Так как мы еще не добавили возможность редактирования чисел - в панели администрирования вы увидите только возможность создания групп и пользователей Django.
Для расширения панели администрирования нужно отредактировать файл 'admin.py':
В этом файле мы импортируем существующую модель 'Numbers' из файла 'models.py' и регистрируем следующим способом:
from .models import Numbers
admin.site.register(Numbers)
После сохранения файла и запуска сервера в панели администрирования добавится следующая строчка:
Если вам нужны понятные названия в панели администрирования, то вы можете добавить в файл models.py следующую строку:
После этого панель с числами у вас будет отображаться корректно:
MVT
Разделы, в которых рассматривались 'urls.py', 'models.py' и 'views.py' объединяют в одну аббревиатуру MVT (movel-view-template). Логика работы Django будет так же понятна, если взглянуть на картинку:
Картинки и другие статические файлы
Django не предназначен для передачи статических файлов (css, js, картинки и другие файлы), которые могут передаваться пользователю без изменения. Такой обработкой, обычно, занимаются веб сервера в виде Nginx или Apache. Картинка примерно описывающая процесс такой работы:
В рамках разработки приложения вы можете добавить такую возможность для Django изменив файл 'app/settings.py' следующим образом:
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
BASE_DIR - это переменная, которая была автоматически объявлена раньше в этом же файле и содержит путь до проекта.
А в файл 'app/urls.py' добавить следующую конструкцию:
from django.conf import settings
from django.conf.urls.static import static
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
settings.DEBUG - это переменная в файле 'settings.py'. Если значение этой переменной True - у вас будут выводиться ошибки на сайте поясняющие в чем может быть неисправность. Если проект уже прошел стадию разработки и его видят пользователи - это значение должно быть False т.к. вашими ошибками могут воспользоваться злоумышленники.
Теперь, вы можете создать папки 'media' и 'static':
И выводить на сайт эти файлы следующим путем:
<link rel="stylesheet" href="static/1.css">
<img src="media/1.jpg">
...