Личный кабинет пользователя в Django: пошаговое руководство
За полтора-два часа соберём рабочий личный кабинет на Django 5.x: регистрация, вход, просмотр и редактирование профиля. С кодом, который копируется и запускается.

В конце у вас будет работающий раздел сайта, куда пользователь входит по логину и паролю, видит свои данные и может их изменить. На чистом проекте это занимает полтора-два часа, если Django и Python уже установлены. Мы возьмём Django 5.x и стандартную модель User — своя кастомная модель для первого кабинета не нужна и только запутает.
Регистрацию, вход и выход почти целиком закрывает встроенное приложение django.contrib.auth. Писать всё руками не придётся — большая часть работы это подключить готовые представления и нарисовать шаблоны.
Что нужно иметь до начала
Проверьте это до первой команды, иначе застрянете на середине:
- Python 3.10 или новее (Django 5.x требует минимум 3.10).
- Установленный Django. Проверка:
python -m django --versionдолжна вывести5.x.y. - Созданный проект и хотя бы одно приложение. Если проекта ещё нет — команды покажу в первом шаге.
- Выполненные стартовые миграции (
python manage.py migrate), чтобы таблицы пользователей уже существовали в базе.
База данных подойдёт стандартная SQLite — для учебного кабинета менять её не нужно.
Шаг 1. Проект и приложение
Если проекта ещё нет, создайте его и приложение для кабинета:
# Django 5.x
django-admin startproject mysite
cd mysite
python manage.py startapp accounts
python manage.py migrateПодключите приложение в mysite/settings.py, добавив его в список:
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"accounts", # наше приложение
]Проверка: команда python manage.py runserver запускается без ошибок, а по адресу http://127.0.0.1:8000/ открывается стартовая страница Django.
Шаг 2. Модель профиля
Стандартный User хранит имя, фамилию, email и пароль. Если нужны свои поля — телефон, аватар, дата рождения — их выносят в отдельную модель Profile, связанную с пользователем один к одному. В accounts/models.py:
from django.db import models
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
phone = models.CharField("Телефон", max_length=20, blank=True)
bio = models.TextField("О себе", blank=True)
def __str__(self):
return f"Профиль {self.user.username}"Чтобы профиль создавался автоматически вместе с пользователем, повесьте сигнал. В том же файле:
from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
# создаём профиль только при первом сохранении пользователя
if created:
Profile.objects.create(user=instance)Создайте и примените миграции:
python manage.py makemigrations
python manage.py migrateПроверка: в выводе makemigrations появилась строка вроде Create model Profile, а migrate отработал без ошибок.
Шаг 3. Регистрация, вход и выход
Вход и выход берём готовые из django.contrib.auth. Регистрацию напишем сами — на основе встроенной формы UserCreationForm. В accounts/views.py:
from django.contrib.auth import login
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
def register(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user) # сразу логиним после регистрации
return redirect("profile")
else:
form = UserCreationForm()
return render(request, "accounts/register.html", {"form": form})
@login_required
def profile(request):
# login_required перекинет анонимного на страницу входа
return render(request, "accounts/profile.html")Теперь маршруты. Создайте accounts/urls.py:
from django.urls import path
from django.contrib.auth import views as auth_views
from . import views
urlpatterns = [
path("register/", views.register, name="register"),
path(
"login/",
auth_views.LoginView.as_view(template_name="accounts/login.html"),
name="login",
),
path("logout/", auth_views.LogoutView.as_view(), name="logout"),
path("profile/", views.profile, name="profile"),
]Подключите их в mysite/urls.py:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path("accounts/", include("accounts.urls")),
]Добавьте в settings.py адреса, куда Django перенаправляет после входа и выхода:
LOGIN_URL = "login"
LOGIN_REDIRECT_URL = "profile"
LOGOUT_REDIRECT_URL = "login"Проверка: откройте /accounts/profile/ без входа — вас должно перекинуть на /accounts/login/?next=/accounts/profile/.
Шаг 4. Шаблоны
Создайте папку accounts/templates/accounts/. Три минимальных шаблона.
register.html:
<h1>Регистрация</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Зарегистрироваться</button>
</form>
<a href="{% url 'login' %}">Уже есть аккаунт? Войти</a>login.html:
<h1>Вход</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Войти</button>
</form>profile.html:
<h1>Личный кабинет</h1>
<p>Логин: {{ user.username }}</p>
<p>Email: {{ user.email }}</p>
<p>Телефон: {{ user.profile.phone }}</p>
<p>О себе: {{ user.profile.bio }}</p>
<a href="{% url 'profile_edit' %}">Редактировать</a>
<form method="post" action="{% url 'logout' %}">
{% csrf_token %}
<button type="submit">Выйти</button>
</form>Выход в Django 5.x работает только через POST-запрос. Обычная ссылка <a href="logout"> вернёт ошибку 405 — используйте форму с кнопкой, как выше.Проверка: зарегистрируйтесь через /accounts/register/ — после отправки формы вы окажетесь в кабинете и увидите свой логин.
Шаг 5. Редактирование профиля
Дадим пользователю менять email и поля профиля. Форма в accounts/forms.py:
from django import forms
from .models import Profile
class ProfileForm(forms.ModelForm):
email = forms.EmailField(label="Email", required=False)
class Meta:
model = Profile
fields = ["phone", "bio"]Представление в accounts/views.py:
@login_required
def profile_edit(request):
profile = request.user.profile
if request.method == "POST":
form = ProfileForm(request.POST, instance=profile)
if form.is_valid():
form.save()
# email хранится в User, а не в Profile — сохраняем отдельно
request.user.email = form.cleaned_data["email"]
request.user.save()
return redirect("profile")
else:
form = ProfileForm(
instance=profile,
initial={"email": request.user.email},
)
return render(request, "accounts/profile_edit.html", {"form": form})Добавьте маршрут в accounts/urls.py:
path("profile/edit/", views.profile_edit, name="profile_edit"),И шаблон profile_edit.html по образцу register.html — форма с {% csrf_token %}, {{ form.as_p }} и кнопкой сохранения.
Проверка: измените телефон, сохраните — на странице кабинета появится новое значение.
Если не получилось
- RelatedObjectDoesNotExist: User has no profile. Профиль не создался — скорее всего пользователь был заведён до того, как вы добавили сигнал. Создайте суперпользователя заново или добавьте профиль вручную через
python manage.py shell. - TemplateDoesNotExist: accounts/login.html. Django не видит шаблон. Проверьте путь: файл лежит в
accounts/templates/accounts/, а приложениеaccountsесть вINSTALLED_APPS. НастройкаAPP_DIRSвTEMPLATESдолжна бытьTrue— в новом проекте она такая по умолчанию. - 405 Method Not Allowed при выходе. Выход оформлен ссылкой, а не POST-формой. Используйте форму с кнопкой из шага 4.
- NoReverseMatch: 'profile' is not a valid view function or pattern name. Забыли
name=в маршруте или опечатались в имени. Сверьте имена вurls.pyи в тегах{% url %}. - CSRF verification failed. В форме нет тега
{% csrf_token %}или он стоит вне<form>. Добавьте его первой строкой внутри формы.
Что делать дальше
Кабинет работает, но пока голый. Следующие шаги в порядке пользы:
- Подключите базовый шаблон с общей навигацией через
{% extends %}, чтобы не дублировать разметку. - Добавьте восстановление пароля — в
django.contrib.authесть готовыеPasswordResetViewи сопутствующие представления, нужно только подключить их и настроить отправку почты. - Загрузку аватара делайте через
ImageField— но сначала настройтеMEDIA_ROOTиMEDIA_URL, иначе файл некуда будет сохранять. - Перед выкладыванием в прод переведите
DEBUGвFalseи заполнитеALLOWED_HOSTS. Валидацию паролей проверьте в настройкеAUTH_PASSWORD_VALIDATORS— по умолчанию она уже включена.
Карточки для маркетплейсов: Таблица товаров и папка фотографий на входе — комплект слайдов и описаний на выходе, по требованиям Wildberries и Ozon.
Спросить за 5 ₽Источники: Django documentation: Using the Django authentication system, Django documentation: django.contrib.auth views
Частые вопросы
У меня Django 4.2, а не 5.x — код подойдёт?
Нужна ли своя кастомная модель пользователя вместо стандартного User?
Почему профиль не создался у уже существующего пользователя?
Как сделать так, чтобы после входа пользователь попадал не в профиль, а на другую страницу?
Безопасно ли это для продакшена?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.