Initial commit: Django inventory system

This commit is contained in:
2025-10-22 01:11:06 +03:00
commit d78c43d9a9
93 changed files with 9204 additions and 0 deletions

201
myproject/accounts/views.py Normal file
View File

@@ -0,0 +1,201 @@
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth import login, authenticate, logout
from django.contrib import messages
from django.core.mail import send_mail
from django.conf import settings
from django.urls import reverse
from django.shortcuts import redirect
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.utils.encoding import force_bytes, force_str
from django.contrib.auth.tokens import default_token_generator
from django.contrib.auth.decorators import login_required
from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.forms import PasswordChangeForm
from .forms import CustomUserCreationForm, PasswordResetForm
from .models import CustomUser
import uuid
def register(request):
if request.method == 'POST':
form = CustomUserCreationForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False # Пользователь не активен до подтверждения email
user.save()
# Отправляем письмо с подтверждением
confirmation_url = request.build_absolute_uri(
reverse('accounts:confirm_email', kwargs={'token': user.email_confirmation_token})
)
subject = 'Подтверждение Email'
message = f'Привет {user.name}!\n\nДля подтверждения вашего email перейдите по следующей ссылке: {confirmation_url}\n\nСпасибо за регистрацию!'
from_email = settings.DEFAULT_FROM_EMAIL
recipient_list = [user.email]
# Выводим письмо в консоль, как вы просили
print(f"Письмо для подтверждения:\nТема: {subject}\nСообщение:\n{message}\nПолучатель: {recipient_list}")
# В реальной системе отправили бы письмо:
# send_mail(subject, message, from_email, recipient_list, fail_silently=False)
messages.success(request, 'Пожалуйста, проверьте вашу почту для подтверждения email.')
return redirect('accounts:login')
else:
form = CustomUserCreationForm()
return render(request, 'register.html', {'form': form})
def register_view(request):
if request.method == 'POST':
form = CustomUserCreationForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False # Пользователь не активен до подтверждения email
user.save()
# Отправляем письмо с подтверждением (выводим в консоль)
confirmation_url = request.build_absolute_uri(
f'/accounts/confirm/{user.email_confirmation_token}/'
)
subject = 'Подтверждение Email'
message = f'Привет {user.name}!\n\nДля подтверждения вашего email перейдите по следующей ссылке: {confirmation_url}\n\nСпасибо за регистрацию!'
from_email = 'noreply@example.com' # Используем значение из настроек
recipient_list = [user.email]
# Выводим письмо в консоль, как вы просили
print(f"Письмо для подтверждения:\nТема: {subject}\nСообщение:\n{message}\nПолучатель: {recipient_list}")
messages.success(request, 'Пожалуйста, проверьте вашу почту для подтверждения email.')
return redirect('accounts:login') # Перенаправляем на страницу входа после регистрации
else:
form = CustomUserCreationForm()
return render(request, 'register.html', {'form': form})
def login_view(request):
if request.method == 'POST':
email = request.POST.get('email')
password = request.POST.get('password')
# Используем email как логин
user = authenticate(request, username=email, password=password)
if user is not None:
if user.is_email_confirmed: # Проверяем, подтвержден ли email
login(request, user)
# Перенаправляем на главную страницу после успешного входа
next_page = request.GET.get('next', 'index') # Если есть параметр next, переходим туда
return redirect(next_page)
else:
messages.error(request, 'Пожалуйста, подтвердите ваш email для входа.')
else:
messages.error(request, 'Неверный email или пароль.')
return render(request, 'login.html')
def logout_view(request):
logout(request)
return redirect('index')
@login_required
def profile_view(request):
return render(request, 'profile.html', {'user': request.user})
@login_required
def change_password_view(request):
if request.method == 'POST':
form = PasswordChangeForm(request.user, request.POST)
if form.is_valid():
user = form.save()
update_session_auth_hash(request, user) # Important for keeping the user logged in
messages.success(request, 'Ваш пароль был успешно изменен!')
return redirect('profile')
else:
messages.error(request, 'Пожалуйста, исправьте ошибки в форме.')
else:
form = PasswordChangeForm(request.user)
return render(request, 'change_password.html', {'form': form})
def confirm_email(request, token):
user = get_object_or_404(CustomUser, email_confirmation_token=token)
if user.is_email_confirmed:
messages.info(request, 'Email уже был подтвержден.')
else:
user.confirm_email()
user.is_active = True # Активируем пользователя
user.save()
messages.success(request, 'Email успешно подтвержден! Теперь вы можете войти.')
return redirect('accounts:login')
def password_reset_request(request):
if request.method == 'POST':
form = PasswordResetForm(request.POST)
if form.is_valid():
email = form.cleaned_data['email']
try:
user = CustomUser.objects.get(email=email)
# Генерируем токен восстановления
user.password_reset_token = uuid.uuid4()
user.save()
# Отправляем письмо с инструкциями по восстановлению
reset_url = request.build_absolute_uri(
reverse('accounts:password_reset_confirm', kwargs={'token': user.password_reset_token})
)
subject = 'Восстановление пароля'
message = f'Привет {user.name}!\n\nДля восстановления пароля перейдите по следующей ссылке: {reset_url}\n\nЕсли вы не запрашивали восстановление пароля, проигнорируйте это письмо.'
from_email = settings.DEFAULT_FROM_EMAIL
recipient_list = [user.email]
# Выводим письмо в консоль
print(f"Письмо для восстановления пароля:\nТема: {subject}\nСообщение:\n{message}\nПолучатель: {recipient_list}")
messages.success(request, f'Инструкции по восстановлению пароля отправлены на {email}')
except CustomUser.DoesNotExist:
# Для безопасности не сообщаем, что пользователя не существует
messages.success(request, 'Если аккаунт с таким email существует, инструкции по восстановлению пароля были отправлены на него.')
return redirect('accounts:login')
else:
form = PasswordResetForm()
return render(request, 'login.html', {'form': form})
def password_reset_confirm(request, token):
try:
user = CustomUser.objects.get(password_reset_token=token)
except CustomUser.DoesNotExist:
messages.error(request, 'Ссылка для восстановления пароля недействительна.')
return redirect('index')
if request.method == 'POST':
password1 = request.POST.get('password1')
password2 = request.POST.get('password2')
if password1 and password2 and password1 == password2:
user.set_password(password1)
user.password_reset_token = None # Обнуляем токен
user.save()
messages.success(request, 'Пароль успешно изменен. Теперь вы можете войти.')
return redirect('accounts:login')
else:
messages.error(request, 'Пароли не совпадают.')
# Отображаем форму смены пароля
return render(request, 'accounts/password_reset_confirm.html', {'user': user})