In this tutorial we will create a landing page for a music releases notifications application in Django. To begin, we need to create a Django project.
Creating a Django project
I will assume you have Django installed but in case you don’t, you can use the official installation guide.
To create a project run the following command in your terminal
django-admin startproject mun
And after the project is created go to its directory via cd
command
And starting a server is as simple as
python manage.py runserver
After visiting 127.0.0.1:8000
you should see a screen that everything is great…
Except it’s not your landing page…
Where do we start?
To add a landing page we need to create an «app» which is a Django concept for things that are not coupled to your app and can be extracted from it (for example authentication which can be used in other applications too).
But let’s not get into that too much and just create a simple app called «pages» which will only contain static pages like «landing», «contact us» and «about».
python manage.py startapp pages
When the app is ready, we need to add it to Django’s INSTALLED_APPS
. We’ll Just append our app to the end of those other ones because we’re going to need some of those.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'pages',
]
The newly created pages
app has a new pages
folder with a couple of python files. Particular ones that interest us are pages/urls.py
and pages/views.py
.
URLs
When a request comes to the server, Django has to find a «view», a function that will process the request and send the response. The way Django finds how to connect a URL that came with the request and a view is via urlpatterns
which are located in your project’s main directory. In my case, it’s mun/urls.py
.
In order to show our landing page on 127.0.0.1:8000
and essentially on our main domain we need to add the following code to pages/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
A path is what comes after a domain in a URL. For example, in the URL https://www.google.com/search?q=mun
the path would be /search?q=mun
. Since we want our landing page to be on the /
path the first parameter we provide to the path
method is ''
. The second argument is what view we need to render which is an index
view in our case.
We also need to add urlpatterns
from our app to the main project’s urlpatterns
with a built-in function include
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('', include('pages.urls')),
path('admin/', admin.site.urls),
]
The view
If you recall, the index
view is not yet created so let’s go ahead and create it in pages/views.py
from django.shortcuts import render
def index(request):
return render(request, 'pages/index.html')
Our index
action simply renders a 'pages/index.html'
template which is again, not yet created. So let’s create it.
The template
I want the landing page to contain the project’s name, a brief description and a list of features.
First, let’s start with the header. Our sign in buttons won’t do anything right now so their href
is #
(which means it won’t do anything) for now. We’ll fix that in the next story.
<header class="header">
<div class="header-text">Sign in via:</div>
<a href="#" class="header-link">Spotify</a>
<a href="#" class="header-link">Deezer</a>
</header>
Second, let’s add the brand name and a description
<section class="landing-section landing-main">
<h1 class="brand">MuN</h1>
<h2>
<span class="brand-text">Mu</span>sic
<span class="brand-text">N</span>otifications
</h2>
<p class="landing-main-text">
Got tired of missing out on releases from your favourite artists?
<br>
You have found a perfect solution...
</p>
</section>
Third, a list of features:
<section class="landing-section langing-features">
<section class="landing-feature feature-music-services">
<h2>Connect your favourite <span class="brand-text">mu</span>sic services</h2>
<ul>
<li>Spotify</li>
<li>Deezer</li>
</ul>
</section>
<section class="landing-feature feature-notifications">
<h2>Get <span class="brand-text">n</span>otifications wherever you want them</h2>
<ul>
<li>Email</li>
<li>Telegram</li>
</ul>
</section>
</section>
However, if we check our browser now we’ll see a not so pleasant picture:
A CSS is a static file
To add CSS to the template Django has a whole app called django.contrib.staticfiles
. By default , Django looks for static files in static
folders of all apps. To add styles to the template we need to tell Django that we’re going to use static files and add a stylesheet tag like so:
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'pages/style.css' %}">
We’ll also need the following line so that our page looks good on mobile
<meta name="viewport" content="width=device-width, initial-scale=1">
And while we’re at it, let’s add a title for our page
<title>MuN: Music Notifications</title>
Here’s the full code glued together:
{% load static %}
<title>MuN: Music Notifications</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="{% static 'pages/style.css' %}">
<header class="header">
<div class="header-text">Sign in via:</div>
<a href="#" class="header-link">Spotify</a>
<a href="#" class="header-link">Deezer</a>
</header>
<section class="landing-section landing-main">
<div class="landing-section-content">
<h1 class="brand">MuN</h1>
<h2>
<span class="brand-text">Mu</span>sic
<span class="brand-text">N</span>otifications
</h2>
<p class="landing-main-text">
Got tired of missing out on releases from your favourite artists?
<br>
You have found a perfect solution...
</p>
</div>
</section>
<section class="landing-section langing-features">
<section class="landing-feature feature-music-services">
<h2>Connect your favourite <span class="brand-text">mu</span>sic services</h2>
<ul>
<li>Spotify</li>
<li>Deezer</li>
</ul>
</section>
<section class="landing-feature feature-notifications">
<h2>Get <span class="brand-text">n</span>otifications wherever you want them</h2>
<ul>
<li>Email</li>
<li>Telegram</li>
</ul>
</section>
</section>
Adding some style
To begin with, I would like to have a full-screen picture in the background with the project’s name and the description in the middle.
We can do the text in the middle with the flexbox. First, we need to make our landing-section
container width and height to full screen. CSS has a special unit for that: viewport height (or vh
) and viewport width (or vw
). If we set them both to 100
it would take the whole screen (or viewport).
However, if we have too much content and the screen is too small (a mobile phone for example) then we’d need to show more content than 100vh
. We can use min-height
instead of height
for that.
.landing-section {
min-height: 100vh;
width: 100vw;
}
Now that we have our container take up the full screen we can position the content in the center with the flexbox. First of all, we need to set display: flex
to use flexbox. Then we can use align-items: center
and justify-content: center
to position the content in the center.
There is only one problem left which is the direction of the content. The fix for it is pretty strait-forward — adding flex-direction: column
.
For more flexbox, I recommend reading this guide.
Here’s how our final landing-section
class looks like
.landing-section {
min-height: 100vh;
width: 100vw;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
The image in the background
I’ve used Unsplash to find the image that would fit my preference.
I set the image as a background with a little help of CSS-Tricks.
.landing-main {
background: url(https://images.unsplash.com/photo-1460667262436-cf19894f4774) no-repeat center center fixed;
background-size: cover;
}
However, the image has light and dark colors and I couldn’t use neither black nor white colors over it. So I decided to add a little overlay and make the text white (or rather light-grey because white is too strong).
.landing-section-content {
padding: 2rem;
background: rgba(0,0,0,0.5);
width: 100vw;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
color: #ccc;
}
.brand {
margin: 0;
color: #c55e00;
}
.brand-text {
color: #c55e00;
}
And a bit of styling for the header…
.header {
width: 100vw;
display: flex;
justify-content: flex-end;
top: 0;
left: 0;
position: absolute;
background: rgba(0,0,0,0.5);
}
.header-link {
margin: 1rem;
border-bottom: 3px solid #c55e00;
font-size: 1.2rem;
color: #222;
text-decoration: none;
color: #ccc;
}
.header-text {
margin: 1rem;
font-size: 1.2rem;
color: #ccc;
}
And here’s what I got:
If you have any ideas for the features part, please, write them in the comments because it currently looks pretty awful.
One more thing
We’ve got most things done by now, however, there is one more. It’s the icon. I like LogoMark website for this purpose. It is very simple to use and has a lot of beautiful icons and stuff.
When you download the icon, it gets saved in .png
extension but .ico
is better for an icon. ICOConverter is a great website for it.
After you download the icon in .icon
extension, just copy it to the pages/static
folder of your project and add 1 line to the index.html
template:
<link rel="shortcut icon" href="{% static 'favicon.ico' %}"/>
Conclusion
In this story I’ve covered:
- how to create a Django project
- Django’s apps concept
- how Django uses
urlpatterns
to find your view - how to write HTML for your landing page
- how to style your landing page so that it looks good
- and the cherry on top of the cake — your icon
This is the first part of the series of articles about the MuN. Stay tuned for part 2. You can find the code of this project, as well as my other projects, on my GitHub page. If you liked this article you can follow me and if you didn’t — you can leave an angry comment down below.
В данном уроке мы создадим, протестируем и опробуем приложение Pages
, у которого будет своя домашняя страница, а также страница с описанием проекта. Мы изучим классовые представления и шаблоны Django, что являются своеобразными кирпичиками в составе более сложных приложений.
Содержание статьи
- Начальная настройка приложения в Django
- Шаблоны в Django
- Классовые представления в Django
- Настройка URL для приложений в Django
- Создание новой страницы «О нас» в Django
- Расширяем возможности шаблона в Django
- Пишем тесты для Django приложений
- Работа с Git и GitHub
- Локальный веб-сервер или Продакшн?
- Запускаем сайт на Django через Heroku
- Дополнительные файлы приложения Django
- Размещение Django сайта на Heroku
Начальная настройка приложения Django включает следующие этапы:
- создание директории для кода;
- установка Django в новом виртуальном окружении;
- создание нового проекта в Django;
- создание нового приложения
pages
; - обновление файла
settings.py
.
Будучи в командной строке, убедитесь, что вы сейчас не находитесь в действующем виртуальном окружении. Если перед знаком доллара ($
) есть текст в скобках, значит, окружение активно. Выполните команду exit
и деактивируйте его.
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Telegram Чат & Канал
Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
Создаем новую директорию под названием pages
на рабочем столе или в любом другом месте. Главное, чтобы папка была легко доступной и не пересекалась с другими проектами.
В заново открытой командной строке наберите следующее:
$ cd ~/Desktop $ mkdir pages && cd pages $ pipenv install django==3.0.* $ pipenv shell (pages) $ django—admin startproject pages_project . (pages) $ python manage.py startapp pages |
Откройте в вашем текстовом редакторе файл settings.py
. В самом низу списка проектов INSTALLED_APPS
добавьте приложение pages
:
# pages_project/settings.py INSTALLED_APPS = [ ‘django.contrib.admin’, ‘django.contrib.auth’, ‘django.contrib.contenttypes’, ‘django.contrib.sessions’, ‘django.contrib.messages’, ‘django.contrib.staticfiles’, ‘pages.apps.PagesConfig’, # новое ] |
Запускаем локальный сервер при помощи команды runserver
:
(pages) $ python manage.py runserver |
Затем переходим на http://127.0.0.1:8000/
.
Приветственная страница Django
Шаблоны в Django
Каждый веб-фреймворк нуждается в удобном способе генерации файлов HTML. В Django за это отвечают шаблоны: индивидуальные файлы HTML, которые связаны между собой и включают базовые логические операции.
Вспомним, что в предыдущей уроке на сайте «Hello, World» фраза была вписана сразу в код файла views.py
как строка игнорируя какие либо HTML шаблоны. Технически это работает, но масштабируется не очень хорошо. Предпочтительнее будет связать представление (View) с шаблоном (Template), таким образом отделяя информацию из каждого.
В данном уроке мы научимся использовать шаблоны для создания домашней страницы и страницы с описанием проекта. В дальнейшем можно будет использовать шаблоны при создании сайтов с сотнями, тысячами и даже миллионами страниц, используя при этом минимальное количество кода.
Для начала нужно определить, где поместить шаблоны внутри структуры проекта Django. Есть два варианта. По умолчанию загрузчик шаблонов Django осмотрит каждое приложение, выискивая связанные шаблоны. Тем не менее, структура остается несколько запутанной: каждое приложение нуждается в новой директории templates
, другой директории с таким же названием, как и у приложения, а также в файле шаблона.
Следовательно, рассматривая приложение pages
, Django будет ожидать следующую структуру:
└── pages ├── templates ├── pages ├── home.html |
Отсюда следует, что нам нужно будет создать новую директорию templates
, новую директорию с названием приложения pages
и сам шаблон под названием home.html
.
Зачем использовать этот, казалось бы, репетативный подход? Короткий ответ заключается в том, что загрузчик шаблонов Django должен наверняка найти подходящий шаблон! Что случится, если имеются два различных файла
home.html
в пределах двух различных приложений? Использование данной структуры гарантирует, что конфликтов подобного рода не произойдет.
Существует еще один подход к решению вопроса — это создание одной директории templates
на уровне проекта и размещение там всех шаблонов. Сделав небольшие поправки в файле settings.py
, можно указать Django, чтобы в поисках верного шаблона он рассматривал также эту новую директорию. Именно этот подход мы сейчас используем.
Первым делом покинем запущенный веб-сервер, применив комбинацию CTRL+C
. Затем создадим директорию под названием templates
и файл HTML под названием home.html
.
(pages) $ mkdir templates (pages) $ touch templates/home.html |
После этого нам нужно обновить файл settings.py
и указать Django место новой директории templates
. Это изменение находятся в одну строчку в настройках 'DIRS'
под TEMPLATES
.
# pages_project/settings.py TEMPLATES = [ { ... ‘DIRS’: [os.path.join(BASE_DIR, ‘templates’)], # new ... }, ] |
Затем для файла home.html
добавляем обычный H1 заголовок.
<!— templates/home.html —> <h1>Homepage</h1> |
Вот и все, шаблон готов! Следующим шагом будет конфигурация нашего URL и файлов представления (views.py).
Классовые представления в Django
Ранние версии Django поддерживали только функциональные представления (они же представления на основе функции), однако разработчики довольно быстро поняли, что им приходится повторять из раза в раз один и тот же паттерн. Писать представление, которое составляет список всех объектов в модели. Писать представление, которое показывает только один детализированный элемент модели. И так далее.
Функциональные представления-генерики были введены для того чтобы избавить разработчиков от этих монотонных паттернов. Однако расширить возможности имеющихся представлений или изменить их должным образом оказалось не так уж просто. В результате в Django появились классовые представления-генерики, которые были легкими в использовании и давали возможность приспосабливать имеющиеся представления под нужны наиболее часто встречающихся случаев.
Классы являются фундаментальной частью Python. В нашем представлении для отображения шаблона мы используем встроенный TemplateView. Обновим файл pages/views.py
.
# pages/views.py from django.views.generic import TemplateView class HomePageView(TemplateView): template_name = ‘home.html’ |
Стоит отметить, что был применен стиль CamelCase для представления HomePageView, так как теперь он стал классом. Названия классов, в отличие от названий функций, всегда должны быть написаны с большой буквы. TemplateView
уже содержит все логические операции, необходимые для отображения нашего шаблона, осталось только уточнить название шаблона.
Настройка URL для приложений в Django
На последнем этапе необходимо обновить URLConfs. Обновления требуется делать в двух местах. Первым делом обновляем файл самого проекта pages_project/urls.py
, чтобы отметить наше приложение pages
, а затем внутри приложения pages
мы связываем представления (View) с URL-адресами.
Начнем с файла pages_project/urls.py
.
# pages_project/urls.py from django.contrib import admin from django.urls import path, include # новое urlpatterns = [ path(‘admin/’, admin.site.urls), path(», include(‘pages.urls’)), # новое ] |
Данный код вам уже знаком. На второй строке мы добавляем include
, что нужно для указания существующего URL-адреса для приложения pages
. Затем создаем на уровне приложений файл urls.py
.
(pages) $ touch pages/urls.py |
И затем добавляем следующий код.
# pages/urls.py from django.urls import path from .views import HomePageView urlpatterns = [ path(», HomePageView.as_view(), name=‘home’), ] |
Данный паттерн практически полностью идентичен тому, что мы использовали в прошлом уроке, однако есть одно важное отличие: во время использования классовых представлений в конце названия представления добавляется as_view()
.
Вот и все! Теперь запустите веб-сервер через python manage.py runserver
, а затем откройте http://127.0.0.1:8000/
. Должна открыться новая домашняя страница.
Домашняя страница
Создание новой страницы «О нас» в Django
Процесс добавления страницы «О нас» очень похож на то, что мы только что сделали. Создадим новый файл шаблона, новое представление, а также новый адрес URL.
Закрываем веб-сервер через комбинацию CTRL+C
и создаем новый шаблон под названием about.html
.
(pages) $ touch templates/about.html |
Затем добавляем короткий HTML заголовок.
<!— templates/about.html —> <h1>About page</h1> |
Создаем новое представление для страницы.
# pages/views.py from django.views.generic import TemplateView class HomePageView(TemplateView): template_name = ‘home.html’ class AboutPageView(TemplateView): # новое template_name = ‘about.html’ |
Далее связываем его с URL в about/
.
# pages/urls.py from django.urls import path from .views import HomePageView, AboutPageView # новое urlpatterns = [ path(‘about/’, AboutPageView.as_view(), name=‘about’), # новое path(», HomePageView.as_view(), name=‘home’), ] |
Запускаем сервер при помощи python manage.py runserver
.
В браузере переходим по адресу http://127.0.0.1:8000/about
. У вас должна появиться новая страница — «About page».
Страница «О Нас»
Расширяем возможности шаблона в Django
Главная сила шаблонов в их способности расширяться. Если задуматься, то на большинстве сайтов есть содержимое, которое повторяется на каждой странице (заголовки, футеры и так далее). Для разработчиков было бы здорово иметь одно установленное место для кода заголовка, которое бы передавалось по наследству каждому шаблону.
Это возможно! Создадим HTML-файл base.html
, у которого будет заголовок с ссылками на две созданные нами страницы. Название для файла можно выбрать любое, в данной случае base.html
просто стало традицией. Теперь закрываем веб-сервер CTRL+C
и затем создаем новый файл.
(pages) $ touch templates/base.html |
В Django, шаблонный язык для добавления ссылок и базовых логических операций минимален. Ознакомиться со встроенным списком шаблонных тегов можно в официальной документации. Шаблонные теги оформляются так {% something %}
, где «something» сам по себе является тегом. Вы даже можете создать собственные шаблонные теги.
Для добавления URL-ссылок в проект мы можем использовать встроенный шаблонный тег url, который присваивает себе имя URL паттерна в качестве аргумента. Помните, как мы добавляли опциональные URL названия двум адресам в pages/urls.py
? Это было сделано именно по этой причине. Тег url
использует эти названия для автоматического создания ссылок.
URL путь для нашей домашней страницы был назван home
, поэтому для настройки ссылки к ней мы будем использовать: {% url 'home' %}
.
<!— templates/base.html —> <header> <a href=«{% url ‘home’ %}»>Home</a> | <a href=«{% url ‘about’ %}»>About</a> </header> {% block content %} {% endblock content %} |
Внизу мы добавляем тег-блок под названием content
. При наследовании, блоки могут быть переписаны дочерними шаблонами. Закрывающему тегу можно дать название endblock
— просто напишите {% endblock %}
. Это может стать хорошей подсказкой при ориентировке в крупных файлах шаблонов.
Обновим файлы home.html
и about.html
для расширения шаблона base.html
. Это значит, что мы будем заново использовать код из одного шаблона в другой. Язык шаблонов в Django поставляется вместе с методом extends, который мы сейчас используем.
<!— templates/home.html —> {% extends ‘base.html’ %} {% block content %} <h1>Homepage</h1> {% endblock content %} |
и
<!— templates/about.html —> {% extends ‘base.html’ %} {% block content %} <h1>About page</h1> {% endblock content %} |
Запускаем сервер с python manage.py runserver
и открываем страницы http://127.0.0.1:8000/
и http://127.0.0.1:8000/about
вновь. Как видите, на обоих страницах появились заголовки.
Неплохо, правда?
Домашняя страница с заголовком
Страница «About» с заголовком
С шаблонами можно осуществить множество операций. Обычно создается файл base.html,
а затем в проекте добавляются дополнительные шаблоны которые расширяют базовый файл.
Пишем тесты для Django приложений
Наконец-то мы добрались до тестов. Хотя в приложениях это является базовым концептом, очень важно, чтобы добавление тестов в Django вошло у вас в привычку. Цитируя Джейкоба Каплан-Мосса, одного из создателей Django: «Непротестированный код можно считать сломанным«.
Написание тестов важно, так как это автоматизирует процесс подтверждения того, что код работает должным образом. В приложении, подобном этому, вы сами можете увидеть, что домашняя страница и страница с описанием проекта на месте и содержат все необходимые данные. Однако с ростом нашего проекта, будет увеличиваться и количество веб-страниц, поэтому идея самостоятельной проверки сотен или даже тысяч страниц не представляется возможной.
Кроме того, когда мы делаем определенные изменения в коде — добавляем новый функционал, изменяем существующий, удаляем неиспользуемые элементы сайта — мы должны быть уверены в том, что все оставшиеся аспекты сайта по-прежнему работают должным образом. Автоматические тесты действуют таким образом, что компьютер каждый раз будет проверять работоспособность проекта, отталкиваясь от единожды написанного ранее правильного кода. К счастью, в Django есть встроенные инструменты для написания и запуска тестов.
# pages/tests.py from django.test import SimpleTestCase class SimpleTests(SimpleTestCase): def test_home_page_status_code(self): response = self.client.get(‘/’) self.assertEqual(response.status_code, 200) def test_about_page_status_code(self): response = self.client.get(‘/about/’) self.assertEqual(response.status_code, 200) |
База данных нам пока не нужна, поэтому сейчас можно использовать простой SimpleTestCase. При наличии базы данных нужно обратиться к TestCase. Затем проводится проверка, в результате которой у каждой страницы должен быть код состояния 200 — это успешный ответ на стандартный HTTP запрос. Таким образом, становится понятно, что запрашиваемая страница действительно существует, но при этом не раскрывается ее содержимое.
Для запуска теста остановите веб-сервер, использовав комбинацию CTRL+C
, а затем наберите в командной строке python manage.py test
:
(pages) $ python manage.py test Creating test database for alias ‘default’... System check identified no issues (0 silenced). .. ——————————————————————————————————— Ran 2 tests in 0.014s OK Destroying test database for alias ‘default’... |
Все успешно! В будущем мы будем использовать более сложные тесты, особенно это важно при работе с базами данных.
А пока, важно привыкнуть к использованию тестов при каждом добавлении нового аспекта в существующий проект Django.
Работа с Git и GitHub
Пришло время зафиксировать изменения с git и загрузить данные на GitHub. Начнем с инициализации нашей директории.
Используйте git status
для просмотра изменений в коде, а затем git add -A
для их добавления. Теперь мы можем добавить первый коммит.
(pages) $ git status (pages) $ git add —A (pages) $ git commit —m ‘initial commit’ |
На GitHub создаем новое хранилище. Назовем его pages-app
. Не забудьте отметить тип «Private», а затем нажмите кнопку «Create repository».
На следующей страницы пролистайте вниз до фразы «…or push an existing repository from the command line». Скопируйте текст и вставьте две команды в терминале.
Все должно выглядеть, так как указано ниже, только вместо wsvincent
в качестве имени пользователя будет указано ваше никнейм на GitHub.
(pages) $ git remote add origin https://github.com/wsvincent/pages—app.git (pages) $ git push —u origin master |
Локальный веб-сервер или Продакшн?
До этого момента, для запуска приложения Pages локально на компьютере мы использовали внутренний веб-сервер Django. Однако локальным адресом нельзя ни с кем поделиться. Для того чтобы запустить сайт в Интернете, сделав его доступным для всех, необходимо разместить код на внешнем сервере. Данный процесс получил английское название продакшн, под которым понимается процесс эксплуатации программы реальными людьми через интернет. Локальные данные доступны только на компьютере разработчика, а продакшн-код находятся на внешнем сервере и становятся доступными для всех.
Существует великое множество серверов. Мы будем использовать Heroku. Для небольших проектов его можно использовать бесплатно, а несложный процесс размещения кода позволил Heroku завоевать большую популярность.
Запускаем сайт на Django через Heroku
Можете бесплатно зарегистрироваться на сайте Heroku. После подтверждения электронной почты вы будете перенаправлены на главную страницу.
Главная страница Heroku
Теперь необходимо установить Heroku Command Line Interface (CLI), необходимый для работы с командной строкой. Нам нужно установить Heroku глабально — таким образом он будет. Откройте новую вкладку командной строки при помощи комбинации CTRL+T
, которая подходит как для Mac, так и для Windows.
Работая на Mac, в новой вкладке при помощи Homebrew установите Heroku:
$ brew install heroku/brew/heroku |
Пользователям Windows нужно выбрать 32-битную или 64-битную версию установщика на странице загрузки Heroku CLI. Для пользователей Linux на сайте Heroku предусмотрены специальные инструкции для установки.
Установка Heroku на Ubuntu
sudo snap install —classic heroku |
После завершения установки можете закрыть используемую вкладку и вернуться к главной вкладке с активным виртуальным окружением pages
.
Наберите команду heroku login
, после чего используйте только что установленные адрес электронной почты и пароль для Heroku.
(pages) $ heroku login Enter your Heroku credentials: Email: will@wsvincent.com Password: ********************************* Logged in as will@wsvincent.com |
Дополнительные файлы Django-приложения
Перед размещением кода на Heroku, нам понадобится сделать четыре изменения в нашем проекте Pages:
- обновить
Pipfile.lock
; - создать новый файл
Procfile
; - установить на нашем веб-сервере
Gunicorn
; - изменить строчку в файле
settings.py
.
Внутри уже существующего файла Pipfile
уточним используемую версию Python — в нашем случае 3.8. Для этого добавим в нижней части файла следующие две строчки.
Pipfile
[requires] python_version = «3.8» |
Далее запускаем pipenv lock
для генерации подходящего Pipfile.lock
.
В действительности, в поисках информации о виртуальном окружении, Heroku заглядывает внутрь нашего Pipfile.lock. По этой причине здесь нам пришлось добавить настройку версии языка программирования.
Затем создаем Procfile
, который является специфическим файлом конфигурации для Heroku.
Откройте Procfile
при помощи текстового редактора и добавьте следующее:
web: gunicorn pages_project.wsgi —log—file — |
Это говорит о том, что нам надо использовать Gunicorn, что является сервером, подходящем для продакшена, в то время как собственный сервер Django работает только в локальном окружении. Устанавливаем gunicorn при помощи Pipenv.
(pages) $ pipenv install gunicorn==19.9.0 |
Конфигурация для веб-сервера находится в файле wsgi.py, который Django автоматически создает для каждого нового проекта. Он находится в основной папке нашего проекта. Поскольку наш проект называется pages_project
, сам файл находится в pages_project/wsgi.py
.
Последний шаг — небольшое изменение в файле settings.py
. Прокрутите вниз до части ALLOWED_HOSTS
и добавьте '*'
. Результат должен получиться следующим:
# pages_project/settings.py ALLOWED_HOSTS = [‘*’] |
Параметр ALLOWED_HOSTS показывает, какие имена хостов/доменов наш сайт на Django может использовать. Это мера безопасности для предотвращения атак, которые возможны даже при, казалось бы, безопасных конфигурациях веб-сервера.
Однако мы использовали знак звездочки *
, а это значит, что все домены являются приемлемыми. На сайте продакшн-уровня вместо этого вам пришлось бы составить ясный список допустимых доменов.
Для проверки изменений мы выполним команду git status
, добавляем новые файлы и затем коммитим их:
(pages) $ git status (pages) $ git add —A (pages) $ git commit —m «New updates for Heroku deployment» |
Теперь мы можем разместить код на GitHub, создав онлайн копию наших изменений в коде.
(pages) $ git push —u origin master |
Размещение Django сайта на Heroku
Последний шаг — это фактическое размещение кода на Heroku. Если вы раньше настраивали сервер, вы будете поражены тем, как сильно Heroku упрощает данный процесс.
Весь процесс будет состоять из следующих этапов:
- создайте новое приложение на Heroku и вставьте в него наш код;
- настройте взаимодействие с git, то есть так называемый «hook» для Heroku;
- настройте приложение на игнорирование статических файлов;
- для активации приложения в онлайн режим, запустите сервер Heroku;
- посетите приложение, перейдя по предоставленному Heroku URL адресу.
В качестве первого шага можем создать новое приложение Heroku. Для этого в командной строке наберите heroku create
. Heroku создаст случайное имя для нашего приложения, в моем случае это fathomless-hamlet-26076
. Ваше название будет другим.
(pages) $ heroku create Creating app... done, ⬢ fathomless—hamlet—26076 https://fathomless—hamlet—26076.herokuapp.com/ | https://git.heroku.com/fathomless—hamlet—26076.git |
На данный момент нам остается только настроить Heroku. Для этого укажем Heroku проигнорировать статические файлы вроде CSS и JavaScript, которые Django по умолчанию попытается исправить под себя. Выполним следующую команду:
(pages) $ heroku config:set DISABLE_COLLECTSTATIC=1 |
Теперь можем разместить код на Heroku.
(pages) $ git push heroku master |
Если бы мы только что набрали git push origin master
, то код был бы загружен в GitHub, а не в Heroku. Добавление слова heroku
в команду позволяет отправить код на Heroku. Первые несколько раз это может сбивать с толку.
Наконец, нам нужно запустить в онлайн наше Heroku приложение. Поскольку трафик веб-сайтов растет, они нуждаются в дополнительных услугах от Heroku. Однако для нашего основного примера мы можем использовать самый низкий уровень web=1
, который является бесплатным.
Введите следующую команду.
(pages) $ heroku ps:scale web=1 |
Все готово! Последним шагом станет подтверждение того, что наше приложение действительно запущено и работает в режиме онлайн. Если вы выполните команду heroku open
, ваш браузер откроет новую вкладку с URL адресом вашего приложения:
Наш адрес https://fathomless-hamlet-26076.herokuapp.com/
. Вы можете убедиться в этом, вот появившаяся домашняя страница:
Домашняя страница на Heroku
Страница «About» также открылась должным образом:
Страница «About» на Heroku
Вам нет нужды разлогиниваться или покидать свое приложение в Heroku. Оно будет работать само по себе на этом бесплатном уровне.
Заключение
Поздравляю с созданием и размещением своего первого Django проекта в интернете! Мы использовали шаблоны, классовые представления, изучили URLConfs подробнее, добавили базовые тесты и использовали Heroku для публикации нашего сайта.
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»
На чтение 10 мин Просмотров 17.5к. Опубликовано 18.11.2021
Flask — это фреймворк для веб-разработки. В Python есть два модуля, которые можно использовать для веб-разработки: Django и Flask. Однако Flask более легкий и легкий в освоении. В этом руководстве мы создадим очень простой веб-сайт, используя модуль Python Flask.
Для начала устанавливаем колбу:
Содержание
- Шаг 1: минимальное веб-приложение
- Шаг 2: Добавление HTML
- Шаг 3: Добавление CSS
- Шаг 4: добавление изображения
- Шаг № 5: Добавление JavaScript
Шаг 1: минимальное веб-приложение
Минимальное приложение можно найти по адресу https://flask.palletsprojects.com/en/2.0.x/quickstart/#a-minimal-application. Это веб-страница, на которой отображается «Hello World». Первым делом мы создали экземпляр Flask () с аргументом «__name__». Декоратор маршрута используется для того, чтобы сообщить Flask URL-адрес, который активирует написанную нами функцию.
from flask import Flask
app = Flask(__name__)
@app.route(‘/’)
def index():
return «Hello World»if «__name__» == «__main__»:
app.run(debug=True)
Затем в терминале PyCharm введите следующее (где имя моего файла Python — main.py; в вашем случае замените main.py именем вашего файла Python):
set FLASK_APP=main.py
$env:FLASK_APP = «main.py»
flask run
Как только вы запустите «flask run», терминал выдаст URL-адрес с портом. Этот URL: ПОРТ — это место, где загружается веб-страница. Вы всегда можете нажать Control + c, чтобы выйти. В моем случае написано: «Запуск на http://127.0.0.1:5000/ (нажмите CTRL + C, чтобы выйти)». Итак, откройте свой веб-браузер, скопируйте и вставьте указанный URL. В моем случае я скопировал и вставил «http://127.0.0.1:5000/». Также обратите внимание, что предыдущие строки должны запускаться каждый раз, когда вы перезапускаете PyCharm, чтобы он работал:
Шаг 2: Добавление HTML
Первое, что вам нужно сделать, это открыть папку, в которой находится скрипт Python, и создать папку под названием «шаблоны». Когда я впервые запустил это, я попытался указать имя «шаблон» в качестве имени папки, и вся программа вылетела и не работала. Поэтому обязательно назовите папку « Шаблоны ». В этой папке «шаблонов» создайте файл index.html с вашим HTML-кодом. Затем используйте render_template () и передайте index.html в качестве аргумента. Теперь, если вы запустите «flask run» в терминале, ваш HTML-код должен отобразиться:
Мой html-код (index.html) на данный момент выглядит следующим образом:
<!DOCTYPE html>
<html lang=«en»>
<head>
<meta charset=«UTF-8»>
<title>Kalyani‘s Resume</title>
</head>
<body>
<h1>
Kalyani’s Resume
This page will contain my resume
</h1>
</body>
</html>
И мой код файла Python (main.py) выглядит следующим образом:
from flask import Flask, render_template
app = Flask(__name__)
@app.route(‘/’)
def index():
return render_template(«index.html»)if «__name__» == «__main__»:
app.run(debug=True)
Последний будет отображать простую HTML-страницу.
Шаг 3: Добавление CSS
Теперь я хочу добавить CSS в свой HTML. Для этого создайте папку с именем «static» и создайте файл с именем «main.css». Здесь имя фактического файла CSS может быть любым. Я решил назвать свой «main.css». Однако имя папки должно быть «статическим»! Фактически, в «статической» папке можно разместить все, что является статическим, например CSS, JavaScript и изображения. Итак, если вы собираетесь размещать изображения, JavaScript и CSS, вы можете создать подпапки.
Сначала напишем нужный мне CSS (main.css):
body {
margin:0;
color: #333
font-family: verdana;
font-size: 20px;
background-color: rgb(201, 76, 76);
}
.styled {
background-color: #92a8d1;
font-family: verdana;
font-size: 20px;
}
Здесь, в index.html, нам нужно написать & lt; link rel = «stylesheet» type = «text / css» href = «{{url_for (‘static’, filename = ‘main.css’)}}» > в заголовке HTML-файла. Здесь имя файла — это имя файла CSS (у меня main.css). Если, например, «main.css» находится с подпапкой «css», вы должны написать следующее:
<link rel=«stylesheet» type=«text/css» href=«{{ url_for(‘static’, filename=’css/main.css’)}}»>.
После этого вы можете использовать созданный вами CSS. Например, я создал один под названием «стилизованный» и использовал его в классе h1.
Мой файл index.html будет следующим:
<!DOCTYPE html>
<html lang=«en»>
<head>
<meta charset=«UTF-8»>
<title>Kalyani‘s Resume</title>
<link rel=»stylesheet» type=»text/css» href=»{{ url_for(‘static‘, filename=’main.css‘)}}»>
</head>
<body><h1 class=»styled»>
Kalyani’s Resume
This page will contain my resume
</h1>
</body>
</html>
Главный файл Python — main.py — остается прежним.
from flask import Flask, render_template
app = Flask(__name__)
@app.route(‘/’)
def index():
return render_template(«index.html»)if «__name__» == «__main__»:
app.run(debug=True)
Шаг 4: добавление изображения
Теперь давайте добавим изображение на созданную HTML-страницу! Для этого мы используем созданную нами «статическую» папку. Внутри «статической» папки я создал другую папку под названием «изображения». В папке изображений я поместил изображение. Теперь давайте добавим изображение в HTML-код следующим образом: <img src = ”/ static / images / kalyani.jpg” height = ”200 ″ />. В этом случае я установил высоту изображения на 200, но вы можете изменить ее на все, что захотите, и добавить CSS, если хотите.
HTML-код будет выглядеть следующим образом:
<!DOCTYPE html>
<html lang=«en»>
<head>
<meta charset=«UTF-8»>
<title>Kalyani‘s Resume</title>
<link rel=»stylesheet» type=»text/css» href=»{{ url_for(‘static‘, filename=’main.css‘)}}»>
</head>
<body>
<img src=»/static/images/kalyani.jpg» height=»200″ />
<h1 class=»styled»>
Kalyani’s Resume
</h1>
This page will contain my resume
</body>
</html>
В качестве альтернативы можно также использовать следующее:
<img src=«{{ url_for(‘static’, filename=’images/kalyani.jpg’)}}» height=«200» />.
В этом случае HTML-код будет выглядеть так:
<!DOCTYPE html>
<html lang=«en»>
<head>
<meta charset=«UTF-8»>
<title>Kalyani‘s Resume</title>
<link rel=»stylesheet» type=»text/css» href=»{{ url_for(‘static‘, filename=’main.css‘)}}»>
</head>
<body>
<img src=»{{ url_for(‘static‘, filename=’images/kalyani.jpg‘)}}» height=»200″ />
<h1 class=»styled»>
Kalyani’s Resume
</h1>
This page will contain my resume
</body>
</html>
Шаг № 5: Добавление JavaScript
Есть два способа добавить JavaScript. В этой первой демонстрации я создам кнопку. Когда кнопка нажата, она активирует функцию myFunction (), которая будет JavaScript (находится в теге <script>). Для этого настройте кнопку. Затем установите тег скрипта в заголовке HTML-кода и определите в нем функцию. В моем случае я определил функцию, которая будет добавлять «все резюме» к элементу ap при нажатии кнопки.
Вы можете добавить его в файл index.html следующим образом:
<!DOCTYPE html>
<html lang=«en»>
<head>
<meta charset=«UTF-8»>
<title>Kalyani‘s Resume</title>
<link rel=»stylesheet» type=»text/css» href=»{{ url_for(‘static‘, filename=’main.css‘)}}»>function myFunction() {
document.getElementById(«para»).innerHTML = «WHOLE RESUME»;
}
</script>
</head>
<body>
<img src=»/static/images/kalyani.jpg» height=»200″ />
<h1 class=»styled»>
Kalyani’s Resume
</h1>
This page will contain my resume
<br>
<br>
<p id=«para»> </p>
<<button id=«button» type=«button» onclick=«myFunction()»> Click to see Resume </button>
</body>
</html>
Однако в большинстве случаев файлы JavaScript, как правило, сами по себе являются документами, а не однострочниками. В таких случаях у нас будет файл.js, который нужно связать. В моем случае я бы написал: <script src = ”/ static / javascript / javascript.js”> </script>. Итак, как и в случае с файлом изображения, мы связываем файл js следующим образом:
<!DOCTYPE html>
<html lang=«en»>
<head>
<meta charset=«UTF-8»>
<title>Kalyani‘s Resume</title>
<link rel=»stylesheet» type=»text/css» href=»{{ url_for(‘static‘, filename=’main.css‘)}}»>
<script src=»/static/javascript/javascript.js»>
</script>
</head>
<body>
<img src=»/static/images/kalyani.jpg» height=»200″ />
<h1 class=»styled»>
Kalyani’s Resume
</h1>
This page will contain my resume
<br>
<br>
<p id=«para»> </p>
<button id=«button» type=«button» onclick=«myFunction()»> Click to see Resume </button>
</body>
</html>
В качестве альтернативы вы также можете использовать это: <script src = ”{{url_for (‘static’, filename = ‘javascript / javascript.js’)}}”> </script>. Последний сгенерирует этот HTML-код:
<!DOCTYPE html>
<html lang=«en»>
<head>
<meta charset=«UTF-8»>
<title>Kalyani‘s Resume</title>
<link rel=»stylesheet» type=»text/css» href=»{{ url_for(‘static‘, filename=’main.css‘)}}»><script src=»{{ url_for(‘static‘, filename=’javascript/javascript.js‘)}}»>
</script>
</head>
<body>
<img src=»{{ url_for(‘static‘, filename=’images/kalyani.jpg‘)}}» height=»200″ /><h1 class=»styled»>
Kalyani’s Resume
</h1>
This page will contain my resume
<br>
<br>
<p id=«para»> </p>
<button id=«button» type=«button» onclick=«myFunction()»> Click to see Resume </button>
</body>
</html>
Заключение
Flask — это микро-фреймворк, который удобен в использовании и отлично подходит для начинающих. В частности, сама документация великолепна, и ее можно найти по адресу https://flask.palletsprojects.com/en/2.0.x/quickstart/#static-files. В этом руководстве мы узнали, как создать простой веб-сайт, добавить CSS, добавить изображения и добавить JavaScript на веб-сайт с помощью модуля Python Flask. Мы надеемся, что эта статья оказалась для вас полезной, и, пожалуйста, ознакомьтесь с Linux Hint для получения более информативных статей.
Современные веб-сайты, требующие сложного взаимодействия с пользователем, создаются с использованием специальных фронтенд-фреймворков, таких как React, Vue.js и другие. Каждый из них имеет свои плюсы и минусы. Вам приходится учитывать скорость разработки с применением выбранного фреймворка, стоимость хостинга, SEO-оптимизацию, различия в синтаксисе и, в некоторых случаях, дублирование бизнес-логики.
Создавая сайт на Django, вы можете получить не менее впечатляющие результаты, чем при работе с JS-фреймворками. При этом Django не столь сложен, требует меньше кода и меньше времени на разработку.
В этой статье мы вам расскажем, как за 20 минут создать несложный сайт на Django.
Реализовать необходимые нам функции можно при помощи нескольких технологий (на выбор). Например, можно воспользоваться Sockpuppet, Reaction или Unicorn. Для обеспечения интерактивности приложения без применения пользовательского JavaScript мы применим Unicorn.
Прежде чем начать
Чтобы следовать этому руководству, вам необходимо:
- Базовое понимание веб-фреймворка Django.
- Практическое знание Docker.
Настройка и обзор проекта
Вот краткий обзор приложения, которое мы будем сейчас создавать:
В этом приложении вы можете добавлять и удалять новую книгу, не обновляя страницу. Такой же функционал доступен в одностраничных приложениях.
Для начала клонируйте ветку base из репозитория django-reactive
:
$ git clone https://github.com/Samuel-2626/django-reactive --branch base --single-branch $ cd django-reactive
Мы будем использовать Docker, чтобы упростить настройку и запуск Django с зависимостями. Из корня проекта создайте образы и раскрутите контейнеры Docker:
$ docker-compose up -d --build
Затем примените миграции, создайте суперпользователя и запустите сервер разработки:
$ docker-compose exec web python manage.py migrate $ docker-compose exec web python manage.py createsuperuser $ docker-compose exec web python manage.py run server
Обратите внимание на модель Book
в файле books/models.py. Код должен выглядеть следующим образом:
from django.db import models class Book(models.Model): title = models.CharField(max_length=200) def __str__(self): return self.title
[django_ad_block]
Работа с Unicorn
Unicorn – это компонентный фреймворк, прогрессивно улучшающий стандартное представление Django. Он динамически обновляет DOM с помощью вызовов AJAX в фоновом режиме.
Добавьте Unicorn
к вашим установленным приложениям:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # Third-party "django_unicorn", # new ]
Далее обновите файл urls.py вашего проекта следующим образом:
from django.urls import path, include path("unicorn/", include("django_unicorn.urls")), # new
Как это работает?
Unicorn
– это библиотека с открытым исходным кодом, улучшающая стандартное представление Django. Благодаря этому первоначальная визуализация компонента выполняется быстро и отлично подходит для SEO.- Затем
Unicorn
привязывается к указанным элементам и при необходимости автоматически выполняет вызовы AJAX. - Наконец,
Unicorn
динамически обновляет DOM.
URL проекта, views и template
В этом разделе мы будем настраивать URL-адреса, вьюшки (views
) и шаблоны (template
) нашего проекта.
Для начала обновите файл urls.py следующим образом:
path("", views.index), # new
Далее обновите файл views.py, добавив в него следующий код:
def index(request): return render(request, "index.html", {})
Наконец, обновите файл index.html:
{% load unicorn %} <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Django Books</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous" /> {% unicorn_scripts %} </head> <body> {% csrf_token %} <div class="container"> <h2>Favourite Django Books</h2> {% unicorn 'book' %} </div> </body> </html>
Логика работы
- Мы создали базовый шаблон Django для своего проекта, связав
views
иurls
вместе. - Обратите внимание, что
Unicorn
нужно загрузить в верхней части HTML-шаблона Django. - Мы также добавили
unicorn_scripts
иcrsf_token
в шаблон Django HTML.
Как написано в документации Unicorn, библиотека следует лучшим практикам Django и, следовательно, требует установки CRSF-токена на любой странице, являющейся компонентом. Это гарантирует, что никакие некорректные сообщения AJAX не будут выполнены.
Также Unicorn
имеет концепцию компонентов. Это позволяет обращаться к набору интерактивных функций, которые могут быть помещены в шаблон. Например, мы добавили компонент book
в файл index.html.
Добавление и удаление книг
В этом разделе мы реализуем функцию добавления и удаления книг без обновления браузера с помощью Unicorn
.
Шаг 1
В корне вашего проекта создайте новые папки (unicorn и components) и новый файл с именем book.py.
Шаг 2
В папке unicorn
, которую вы создали ранее, создайте еще одну папку с именем templates
, внутри нее — папку с именем unicorn
и, наконец, внутри этой папки создайте файл с именем book.html
. (У вас должен получиться путь unicorn/templates/unicorn/book.html).
Шаг 3
Внутрь book.html добавьте следующий код:
<div class="row"> <div class="col-md-6"> <section> <ul class="list-group"> {% for book in books %} <li class="list-group-item"> {{ book.title }} <button class="btn btn-outline-danger" style="float: right;" unicorn:click="delete_book('{{ book.id }}')" > Delete Book </button> </li> {% empty %} <p>Database Empty | Add your favourite Django book</p> {% endfor %} </ul> </section> </div> <div class="col-md-6"> <form> <input type="text" class="form-control" placeholder="Enter title of the book..." unicorn:model.defer="title" /> <br /> <button class="btn btn-secondary" style="min-width: 100%;" unicorn:click.prevent="add_book" > Add Books </button> </form> </div> </div>
Что здесь происходит?
Внутри компонента у нас есть доступ к обычному синтаксису Django.
Обратите внимание на элемент input. Всё знакомо, за исключением атрибута unicorn: model
. Он указывает, какое поле в вашем внутреннем компоненте будет привязано к этому вводу. В этом случае имя поля будет title.
Примечание. unicorn: model
– это магия, которая связывает входные данные с компонентом бэкенда.
Обратите внимание на кнопку «Add Books» с атрибутом unicorn:click
. Этот атрибут указывает Unicorn
привязать бэкенд-метод add_book
к событию браузера click
.
Точно так же кнопка «Delete Book» указывает Unicorn
привязать бэкенд-метод delete_book
. Кроме того, мы также передали идентификатор книги в функцию delete_book
, чтобы однозначно идентифицировать каждую книгу.
Чтобы предотвратить появление обновлений при каждом входе, вы можете добавить модификатор lazy
или defer
в конец unicorn:model
.
Атрибуты, используемые в шаблонах компонентов, обычно начинаются с unicorn:
, но также поддерживается шорткат u:
. Обратите внимание, что свойства компонента могут быть многих типов, включая str
, int
, list
, dictionary
, decimal
и Django Model
.
Наконец, Unicorn
требуется один корневой элемент, охватывающий весь шаблон компонента.
Шаг 4
Внутри book.py добавьте следующий код:
from django_unicorn.components import UnicornView from books.models import Book class BookView(UnicornView): title: str = "" books = Book.objects.none() def hydrate(self): self.books = Book.objects.all() def add_book(self): if self.title != "": book = Book(title=self.title) book.save() self.title = "" def delete_book(self, id): try: book = Book.objects.get(id=id) book.delete() except: pass
Объяснение логики кода
- Мы импортируем
UnicornView
, внутренний подклассTemplateView
. Следовательно, процесс перехода от стандартногоview
на основе классов должен быть простым. - При создании экземпляра компонента для получения последних книг из базы данных вызывается метод
hydrate
. Таким образом поддерживается актуальность информации. - Метод
add_book
создает новую модель book из title, сохраняет ее в базе данных, а затем очищает title. - Метод
delete_book
удаляет книгу, соответствующую идентификатору.
Пройдя все описанные шаги, перейдите по адресу http://127.0.0.1:8080/, чтобы убедиться, что приложение работает должным образом. Вы должны увидеть следующее:
Попробуйте добавить или удалить свои любимые книги по Django.
Заключение
Мы разобрали, как создать сайт на Django за 20 минут. Мы создали реактивное веб-приложение с полным стеком на Django, без какого-либо JavaScript. Также мы использовали Unicorn, чтобы иметь возможность добавлять и удалять книги, не обновляя страницу.
Вы можете скачать полный код здесь.
Успехов в написании кода!
Перевод статьи «Full-Stack Reactive Website in Django (No JavaScript)».
Python – популярный язык программирования общего назначения. Он позволяет создавать контент разного направления. Используется и для веб-разработки. Активно применяется при написании собственных веб-страничек.
В данной статье будет рассказано о том, как написать элементарный сайт на Python. Это небольшой туториал, помогающий новичкам освоиться в выбранном направлении. Также предстоит узнать, какие популярные проекты уже были написаны на Питоне. Соответствующие данные помогут понять, насколько на самом деле язык программирования является востребованным и перспективным в 21 веке.
Питон и веб
В Google полно информации о том, как можно сделать собственный сайт. И не только на Питоне, а совершенно на любом языке. Соответствующие сведения позволяют с нуля писать как элементарные, так и весьма сложные странички.
При использовании Python в web development, нужно учитывать следующие особенности:
- инструменты применяются преимущественно для бэкенда и маршрутизации;
- в качестве конкурентов Питона выделяют Ruby и PHP;
- для того, чтобы сделать сайт или веб-утилиту на выбранном ЯП, предстоит выучить CSS и HTML.
Функциональную часть фронтенда можно создать, согласно данным из Google, на JavaScript. Но можно через специальные средства заняться фулл-стек разработкой на Python.
Full Stack Development на Питоне
Для того, чтобы полноценно использовать Питон при написании собственной веб-странички, придется изучить некоторые фреймворки. Они носят название Full Stack Frameworks. Самым распространенным вариантом является Django. С ним всего за 5 минут удастся создать элементарный сайт.
Джанго выделяется:
- простотой изучения;
- наличием шаблонов для специальных HTML-документов;
- возможностью вставки получившегося кода в Python для взаимодействия с информацией из backend.
Фулл-стек позволяет работать с HTTP-запросами, хранилищами БД, а также готовыми шаблонами веб-страниц, запросами маршрутизации. На помощь иногда приходят микрофреймворки, но они применяются более опытными разработчиками. Обладают меньшей гибкостью, из-за чего программный код в конечном итоге усложняется.
Ключевые фреймворки
Если делает website, нужно тщательно составлять запросы для Google. С их помощью удастся найти ответ на любой вопрос, связанный с разработкой программного обеспечения. Но в Google и других поисковых системах легко запутаться. Они редко выдают на первых страницах поэтапные уроки для новичков. Поэтому инструкции, приведенные ниже, подойдут «чайникам» и еще не слишком уверенным в себе пользователям.
Создание новой страницы в интернете на Python лучше проводить при помощи фреймворков. В Google наиболее распространенными «библиотеками» для рассматриваемого направления выступают следующие варианты:
- Django. Самый распространенный фреймворк для веб-разработки. Google указывает на то, что он предусматривает множество встроенных модулей, которые прекрасно совмещаются друг с другом. Сначала нужно вникнуть в алгоритмы создания веб-софта и внутренние структуры Джанго. После этого сделать собственный контент «для интернета» не составит никакого труда. Django отлично масштабируется. Google указывает на то, что поддержка ПО, написанного с этим фреймворком, не отнимет много времени и сил.
- Flask. Второй framework, который поможет при написании веб-страничек. Это, если верить Google, противоположность Django. Понятен новичкам. При разработке предоставляет лишь «базовый функционал». Крупные и оригинальные проекты на Flask сделать никак не получится.
- Pyramid. Что-то среднее между предыдущими двумя фреймворками. Он не такой функциональный, как Джанго, но и не «упрям», как Flask. Google ссылается на то, что Pyramid можно задействовать для большинства веб-софта.
Окончательный выбор фреймворка зависит от того, какой результат хотим получить на выходе. Далее создаем страничку на Python при помощи Django. Это – самое быстрое и рациональное решение.
Написание веб-страницы
Теперь создаем страницу на Python при помощи Django. Такое решение подойдет тем, кто уже знаком в общих чертах с выбранным языком программирования. Он не потребует особых навыков и знаний.
Для того, чтобы сделать веб-проект, предстоит использовать виртуальную машину и Убунту Сервер 18.04. А еще нужно обеспечить на устройстве веб-сервер под названием Apache.
Инициализация компонентов
Делаем всю процедуру поэтапно. Сначала нужно установить необходимые компоненты:
- Инициализировать пакетный менеджер под названием pip.
- Подключить пакет виртуального окружения.
- Перейти в домашнюю директорию. Там делаем виртуальное окружение. Оно будет находиться в ~/venv/.
- Установить Apache. Этот шаг пропускается, если соответствующее ПО уже стоит на задействованном устройстве.
- Активировать виртуальное окружение при помощи source ~/venv/bin/activate.
- Установить на устройство Джанго. Сделать это нужно в Virtual Environment.
Далее предстоит создать проект с сайтом. Для этого лучше сделать отдельную папку. Перейдя туда, остается обеспечить наличие Джанго-проекта. Сделать это помогает команда Django-admin startproject MySite.
Работа в проекте
Теперь создаем основной функционал. Для этого потребуется:
- Перейти в полученный проект.
- Добавить приложение, которое будет называться app. Оно предусматривает основную логику сайта.
- Разрешить все адреса для хостов.
- Запустить получившийся проект. В папке с ним должен появиться управляющий файл manage.py.
- Запустить команду отладочного сервера: python3 manage.py runserver. Сервер заработает. Сайт – тоже. Он обнаружен по адресу 127.0.0.1 на порте 8000.
- В файле models нужно указать классы моделей, которые будут сущностями в базе данных. В Views – прописать концепции MVC в Джанго.
- Создать каталог, в котором хранятся html-странички. В папке проекта нужно сделать папку templates.
- Сделать в каталоге с шаблонами файл index.html.
- Отредактировать файл контроллера. Приведенный пример передает данные на сайт Python. Пусть созданная функция отображает на страничке «Hello, World!».
- Задать адресацию. Для этого нужно перейти в urls и написать желаемый маршрут, по которому отображается страничка.
- Скопировать файл urls в директорию с получившимся приложением.
Google говорит о том, что теперь остается запустить сайт через сервер Apache. Здесь можно посмотреть итоговый исходный код. А тут без помощи Google удастся обнаружить краткий видео обзор относительно программирования страничек на Python.
В материале 3 раздела: в первом описывается процесс создания законченного проекта на Django, в принципе, для понимания основ работы с фреймворком на нем можно и остановиться. Последующие 2 добавляют стили и описывают некоторые дополнительные приемы работы с пользователями.
Пример создания более сложного сайта на Django вы можете найти на моем сайте, посвященном языку Python — python.phpnick.ru
Видеоверсия (Django 4.1). Является больше дополнением и перед просмотром лучше ознакомиться с текстом.
Создание проекта
Создадим папку с названием проекта, например log. В этой папке нужно создать виртуальное окружение. Для этого воспользуемся командой:
python -m venv log_env
После чего созданное виртуальное окружение нужно активировать, для этого в разных ОС используются разные команды.
Для Linux и OS X:
source log_env/bin/activate
Для Windows:
log_envScriptsactivate
Далее нужно установить фреймворк в это виртуальное окружение, с помощью команды:
pip install Django
После того как Django установится, создадим новый проект с помощью команды:
django-admin.py startproject log
После этого будет создана новая папка log, в которую надо перейти. Внутри нее вы увидите файл manage.py. Этот файл мы будем использовать очень часто, на всем протяжении работы с проектом.
Можно сразу попробовать запустить встроенный в Django веб-сервер с помощью команды:
python manage.py runserver
(надеюсь, перед тем как запускать эту команду вы не забыли перейти в папку log/log, там, где вы видите файл manage.py)
Если после запуска сервера вы откроете браузер, и перейдёте по адресу localhost:8000, то вы должны увидеть приветственную страницу Django.
Если страница у вас открылась, значит все в порядке и можно продолжать.
Для хранения записей на сайте нужна БД, на данный момент у нас уже есть sqlite-БД, которая находится в файле db.sqlite3 (рядом с файлом manage.py). Но пока что она пустая, поэтому теперь создадим таблицы в БД, которые потребуются для работы нашего проекта с помощью команды:
python manage.py migrate
Так как проект на Django должен состоять из различных приложений (apps), то теперь нам нужно создать новое приложение в нашем проекте, назовем его logs. Делается это с помощью команды:
python manage.py startapp logs
После чего папка проекта (log/log) будет иметь следующее содержимое:
log/log
|-- log
|-- logs
|-- db.sqlite3
|-- manage.py
Получается, что у нас целых 3 папки log, одна в другой, как в матрёшке. И есть еще папка с названием logs. Постарайтесь не запутаться в них, потому что в дальнейшем нам придется работать отдельно в каждой из них, и очень важно не перепутать в какой что делать.
Чтобы Django узнал о существовании вновь созданного приложения logs, в файле settings.py (папка log/log/log) найдите список INSTALLED_APPS, и добавьте новый элемент с названием приложения – logs. Должно получиться вот так (добавленная строчка выделена жирным):
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'logs',
]
Модель (Model)
Добавим модели Topic и Entry в файл models.py (папка log/log/logs). Модели будут содержать описания о том, какие данные будут храниться в БД-таблицах нашего проекта.
Откроем файл models.py и добавим туда следующее содержимое:
from django.db import models
class Topic(models.Model):
text = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.text
class Entry(models.Model):
topic = models.ForeignKey(Topic, on_delete=models.PROTECT)
text = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = 'entries'
def __str__(self):
return self.text[:50] + "..."
Таблицы моделей Entry и Topic имеют связь один-ко-многим. То есть у каждой основной записи или темы (Topic) может быть много вложенных (Entry).
Теперь осталось создать файл миграции для добавленных моделей и создать новые таблицы в БД на основе этих миграций. Делается это с помощью 2-х команд:
python manage.py makemigrations logs
python manage.py migrate
Создание суперпользователя
Чтобы попасть в админ-панель Django (http://localhost:8000/admin) нужно создать нового пользователя. Делается это командой:
python manage.py createsuperuser
При создании суперпользователя укажите имя пользователя, email (можно не указывать) и пароль.
После добавления нового пользователя можно попробовать войти в админ-панель Django. Если у вас всё получится, то вы должны увидеть следующую картинку:
Здесь вы видите таблицу с 2-мя строчками для работы с группами пользователей (Groups) и с самими пользователями (Users). Для того, чтобы мы здесь могли работать с нашими моделями, их нужно зарегистрировать в файле admin.py (log/log/logs). Откроем файл и добавим в него следующий код:
from django.contrib import admin
from logs.models import Topic, Entry
admin.site.register(Topic)
admin.site.register(Entry)
После этого обновите страницу админ-панели и вы должны увидеть 2 новые строчки: Entries и Topics.
Маршруты (urls)
Нам нужно добавить маршруты, по которым запросы от браузера будут открывать нужные страницы сайта. Для этого следует отредактировать 2 файла с одинаковым названием urls.py, это файл urls.py для всего проекта в целом (папка log/log/log) и для отдельного приложения logs (папка log/log/logs). В папке приложения logs файла urls.py нет, его нужно создать самостоятельно.
Для начала откроем файл urls.py проекта (папка log/log/log). И в список urlpatterns добавим новую строчку (выделена жирным):
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('logs.urls', namespace='logs')),
]
Чтобы не было ошибки нужно в строчку (выше списка urlpatterns):
from django.urls import path
добавить импорт метода include(). После чего эта строчка будет выглядеть следующим образом:
from django.urls import path, include
Далее создадим файл urls.py в папке приложения (папка log/log/logs). Его содержимое должно быть таким:
from django.urls import path
from . import views
app_name = 'logs'
urlpatterns = [
path('', views.index, name='index'),
path('topics/<int:topic_id>/', views.topic, name='topic'),
]
Здесь, в методе path() первым параметром идет url страницы на сайте, 2-й параметр – это метод в файле views (в данном случае index или topic), который должен обрабатывать пришедший запрос от посетителя сайта, 3-й параметр – это произвольное имя данного маршрута, которое может применяться в дальнейшем для обращения к этому маршруту.
Если интересно, то определение метода path() в документации выглядит следующим образом:
path(route, view, kwargs=None, name=None)
Представление (View)
Представление в Django – это контроллер в других фреймворках. Представление получает информацию от модели и отдает её в шаблон (template), который, в свою очередь, нужен для размещения переданной ему информации на html-странице. Класс представления – views.py можно найти в папке приложения logs (log/log/logs). Добавим в него 2 метода из маршрутов, которые мы добавили выше, в файле urls.py приложения (index() и topic()). В результате его содержимое должно быть следующим:
from django.shortcuts import render
from .models import Topic
def index(request):
topics = Topic.objects.order_by('-date_added')
context = {
'topics': topics,
}
return render(request,
'logs/index.html', context)
def topic(request, topic_id):
topic = Topic.objects.get(id=topic_id)
entries = topic.entry_set.order_by('-date_added')
context = {
'topic': topic,
'entries': entries,
}
return render(request,
'logs/topic.html', context)
В обоих методах мы видим метод render(). Он использует html-файлы для вывода полученных из модели данных на страницу в браузере. Это и есть шаблоны. Всего нам нужно будет их 3 штуки, один общий (base.html), который будут наследовать 2 других. Первый (index.html) – для вывода списка основных записей или тем (topics), второй (topic.html) – для вывода какой-то определенной темы, и списка вложенных в нее заметок/записей (entries).
Шаблон (Template)
Для того чтобы добавить нужные нам шаблоны в папке приложения logs (log/log/logs) создадим папку templates, а внутри нее папку с названием приложения logs. Затем внутри папки logs создадим 3 файла: base.html, index.html и topic.html. Содержимое файлов представляет html-код с включениями Django-директив. Особо выпендриваться с html-разметкой я не стал, чтобы не усложнять материал, но вы, конечно, можете сделать всё по-своему.
Содержимое файла base.html следующее:
<p><a href="{% url 'logs:index' %}">
Журнал записей
</a></p>
{% block content %}{% endblock content %}
Вначале выводится ссылка на индексную страницу сайта, обратите внимание, чтобы создать ссылку здесь используется имя маршрута index, которое мы указали ранее в файле urls.py.
Между Django-директивами {% block content %} и {% endblock content %} будет включено содержимое из 2-х других шаблонов (index.html и topic.html).
Содержимое файла index.html следующее:
{% extends 'logs/base.html' %}
{% block content %}
<h3>Темы:</h3>
{% for topic in topics %}
<p>
<strong>
<a href="/topics/{{ topic.id }}/">
{{topic.text}}
</a>
</strong>
(Дата создания: {{topic.date_added|date:'H:i d/m/Y'}})
</p>
{% empty %}
<p>Пока нет тем</p>
{% endfor %}
{% endblock content %}
Содержимое файла topic.html следующее:
{% extends 'logs/base.html' %}
{% block content %}
<h3>Тема: {{topic}}</h3>
{% for entry in entries %}
<p>
{{entry.text|linebreaks}}
(Дата создания: {{entry.date_added|date:'H:i d/m/Y'}})
</p>
{% empty %}
<p>Пока нет записей</p>
{% endfor %}
{% endblock content %}
Теперь в браузере на индексной странице (http://localhost:8000/) можно увидеть следующую картинку:
Добавить темы (topics) и вложенные записи (entries) можно через админку Django.