Теперь перейдем к рассмотрению бэкенда Django. Первым шагом, как всегда, является активация соответствующего виртуального окружения Python. Из папки ./musical_nft_thumbnails
$source env/bin/activate
На данный момент нам нужна посадочная страница. Функции входа, выхода, регистрации, а также сброса пароля. После того как пользователь зарегистрируется и войдет в нашу платформу, мы перенаправим его на его персональную страницу. Там он сможет увидеть свою информацию, NFT, которыми он владеет, и купить новый NFT с помощью криптовалюты или кредитной карты.
Создание нового приложения Django для аутентификации
$py manage.py startapp authentication
В этом вновь созданном приложении мы будем управлять процессом регистрации, входом в систему, выходом из нее и сбросом пароля.
Добавить в musical_nft/settings.py аутентификацию в список установленных приложений:
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
# here =>
"authentication",
]
Теперь в глобальном файле urls.py внутри musical_nft/settings.py добавьте
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path("", include("authentication.urls"))
]
Теперь все пути, которые мы имеем внутри приложения аутентификации, будут подключены к этому проекту urls.py
В папке приложения аутентификации создайте еще один urls.py и передайте в него следующий код
from django.urls import path
from .views import HomeView
urlpatterns = [
path("", HomeView.as_view(), name="home"),
]
Если вы не создали суперпользователя, давайте сделаем это сейчас
$python manage.py createsuperuser
Теперь откройте браузер http:127.0.0.1:8000/admin при запущенном локальном Django-сервере и введите учетные данные суперпользователя (обязательно убедитесь, что ваш postgres-сервер запущен $sudo service postgresql start).

После того как вы вошли в систему, перейдите в раздел ”Пользователь” и добавьте нового пользователя (подтвердите пароль)

На данном этапе нам нужен класс представления аутентификации и несколько html-страниц для рендеринга. При создании приложений Django следует помнить, что это всегда трехступенчатый процесс: определение адресов (в приложении), представлений (в нашем случае представлений на основе классов. Если вы хотите поэкспериментировать с альтернативными реализациями этого кода, то можно сделать представление на основе функций) и шаблоны (html-страница, которая будет отображаться с небольшим количеством добавленных Django-элементов).
В файл views.py приложения аутентификации добавьте следующий код:
from django.shortcuts import render
from django.views.generic import TemplateView
class HomeView(TemplateView):
def get(self, request):
return render(request, "home.html", {})
Только для тестирования создадим простой файл home.html с сообщением, которое будет отображаться в браузере. Для этого создадим в ./muscial_nft_thumbnails/tempaltes/home.html
{% extends "base.html" %}
{% block content%}
<h1> Test screen </h1>
{% endblock content%}
Эти своеобразные фигурные скобки являются частью синтаксиса Django, который мы должны использовать с нашими шаблонами
Затем в settings.py добавьте определение корневой папки шаблона
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [os.path.join(BASE_DIR, "templates")],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
В этом проекте мы будем использовать bootstrap для стилизации. Перейдите на страницу их документации и возьмите из введения второй вариант номер два, Include Bootstrap’s CSS and JS. и вставьте этот код во вновь созданный файл base.html в корневой папке проекта ./templates (или просто скопируйте отсюда)
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Muscial NFT</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
</head>
<body>
<div class="container ">
<br/>
<br/>
{% block content %}
{% endblock content %}
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
</body>
</html>
Теперь добавим navbar на нашу страницу base.html.
Это можно сделать, просто зайдя в документацию сайта bootstrap и поискав navbar в компонентах. Выбираем наиболее понравившийся. Для нашей демонстрации подойдет первый вариант.
Вот отредактированный код, который нужно передать в файл navbar.html в папке ./templates в корневой директории проекта.
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="https://dev.to/ilija/{% url"home' %}">Musical NFT </a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
А затем просто перейдите в ранее созданный файл base.html и добавьте одну новую строку после первого тега body
{% include “navbar.html”%}
Из корневого каталога
$py manage.py runserver
Перейдите в браузер по адресу http://127.0.0.1:8000 и проверьте, появилось ли на экране правильное сообщение.
Теперь, если вы вернетесь в браузер, вы должны увидеть что-то вроде этого

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

Сначала мы доработаем 3 основных шаблона: navbar, base и home (base включает в себя navbar, а home расширяет base, как показывает поток). Следует иметь в виду, что у home будет две возможности: 1) если пользователь залогинен, то мы будем показывать ему его персональную страницу; 2) если пользователь не залогинен, то мы будем предлагать ему формы входа (это можно проверить в файле home.html).
navbar.html (модифицированный bootstrap navbar)
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="https://dev.to/ilija/{% url"home' %}">Musical NFT </a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
{% if user.is_authenticated%}
<li class="nav-item">
<a class="nav-link" href="https://dev.to/ilija/{% url"logout'%}">Logout</a>
</li>
{% else %}
<li class="nav-item">
<a class="nav-link" href="https://dev.to/ilija/{% url"home'%}">Login</a>
</li>
{% endif%}
</ul>
</li>
</ul>
</div>
</div>
</nav>
Теперь base.html включает в себя navbar.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Muscial NFT</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
</head>
<body>
{% include "navbar.html"%}
<div class="container ">
<br/>
<br/>
{% if messages %}
{% for message in messages%}
<div class="alert alert-warning alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{% endfor%}
{% endif %}
{% block content %}
{% endblock content %}
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
</body>
</html>
Здесь я хочу обратить ваше внимание на последний {% block content %} {% endblock content %} Это место, где base.html инжектирует любой другой шаблон, который наследует от него с помощью команды extends (в нашем случае home.html).
Далее несколькими строками выше вы имеете немного странный синтаксис с {% if messages %} {% for message in messages%} Просто таким образом мы передаем в наш шаблон сообщение об успехе или ошибке. Более подробную информацию об этом можно найти в файле view.py.
Как мы видим, home.html будет расширять base.html и иметь внутри себя специфические для Django статусы if/else. Эта строка if/else поможет нам проверить, вошел ли пользователь в систему, после чего мы предложим ему его персональную страницу. В случае если пользователь не вошел в систему, мы покажем ему форму входа.
Ниже приведен пример кода:
{% extends "base.html" %}
{% block content%}
<div class="col-md-6 offset-md-3">
{% if user.is_authenticated %}
<h1> Welcome <h1/>
{% else %}
<h1> Login </h1>
<br/>
<form method="POST" action="https://dev.to/ilija/{% url"home' %}">
{% csrf_token %}
<form>
<div class="mb-3">
<input type="text" class="form-control" aria-describedby="emailHelp" placeholder="Username" name="username" required>
</div>
<div class="mb-3">
<input type="password" class="form-control" placeholder="Password" name="password" required>
</div>
<button type="submit" class="btn btn-secondary">Submit</button>
</form>
</form>
</div>
{% endif %}
{% endblock content%}
Теперь у нас есть все шаблоны, и мы можем перейти в папку authentication app, где нам нужно обновить наш urls.py следующим кодом
from django.urls import path
from .views import HomeView, LogoutUser
urlpatterns = [
path("", HomeView.as_view(), name="home"),
# path("login/", LoginUser.as_view(), name="login"),
path("logout/", LogoutUser.as_view(), name="logout"),
]
Как видно, мы добавили новый путь выхода из системы (логин является частью обычного пути home и класса HomeView), который будет обрабатываться классом LogoutUser внутри authenticaiotn view.py.
Как вы уже догадались, последний кусочек паззла, который нам нужен, это обработчик просмотра, который склеит все эти элементы вместе. Вот пример возможного кода:
from django.shortcuts import render, redirect
from django.views.generic import TemplateView
from django.contrib.auth import authenticate, login, logout
from django.contrib import messages
class HomeView(TemplateView):
template_name="home.html"
def post(self, request):
# check to see if loggin in
if request.method == "POST":
user_name = request.POST["username"]
password = request.POST["password"]
user = authenticate(request, username=user_name, password=password)
if user is not None:
login(request, user)
messages.success(request, "You have been logged in!")
return redirect("home")
else:
messages.success(request, "There was An Error login in, please try again")
return redirect("home")
else:
return render(request, "home.html", {})
class LogoutUser(TemplateView):
def get(self, request):
logout(request)
messages.success(request, "You have been logged out!")
return redirect("home")
В этот момент запустите ваш Django-сервер локально (убедитесь, что ваш postgres-сервер работает и запущен), а затем перейдите по адресу http://127.0.0.1:8000. Если вы вошли в систему как администратор, вы должны увидеть что-то вроде этого

Теперь введите учетные данные администратора или только что созданного пользователя, и вы должны увидеть что-то вроде этого =>

Посмотрите на кнопку выхода из системы в левом верхнем углу навигационной панели. Эта кнопка попадет на наш путь logout/, а затем на обработчик класса LogoutUser (из views.py), который просто выйдет из системы и перенаправит текущего пользователя на домашнюю страницу.
И на этом месте мы, наконец, можем увидеть очень красивый момент в файле home.html. Этот цикл внутри home.html увидит, что пользователь уже не вошел в систему, и покажет ему формат логина. И, в общем-то, благодаря этой приятной детали у нас все в одном месте: и вход, и выход, и профиль пользователя - все прекрасно связано в этом шаблонном цикле.

Теперь, когда у нас есть вход и выход, перейдем к разработке функциональности регистрации и сброса пароля, прежде чем приступать к интеграции с web3.
Код для этого можно найти на github