/
Tikhonuk
/
veb
Обзор
Документация
Войти
/
Tikhonuk
/
veb
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
masterclass/forms.py
163 строки
7 KB
Tikhonuk
Предфинальная версия проекта с Docker, Celery, Mailhog, OAuth2
23 июн 2026, 23:43
23 июн 2026, 23:43
9f6bba3
Код
Авторство
О чём код?
from django import forms from django.contrib.auth.forms import UserCreationForm, AuthenticationForm from .models import User, Role, MasterClass, Category, Schedule, Image, Comment class RegistrationForm(UserCreationForm): """Форма регистрации нового пользователя с выбором роли""" email = forms.EmailField(required=True, label='Email') full_name = forms.CharField(max_length=255, required=True, label='ФИО') phone = forms.CharField(max_length=20, required=False, label='Телефон') ROLE_CHOICES = [ ('user', '👤 Обычный пользователь'), ('creator', '🎓 Создатель мастер-классов'), ] role = forms.ChoiceField( choices=ROLE_CHOICES, widget=forms.RadioSelect, initial='user', label='Роль', required=True, ) class Meta: model = User # ★★★ УБИРАЕМ 'role' ИЗ ПОЛЕЙ ★★★ fields = ('email', 'full_name', 'phone', 'password1', 'password2') widgets = { 'email': forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Email'}), 'full_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Иванов Иван Иванович'}), 'phone': forms.TextInput(attrs={'class': 'form-control', 'placeholder': '+7 123 456-78-90'}), 'password1': forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Пароль'}), 'password2': forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Повторите пароль'}), } def clean_email(self): email = self.cleaned_data.get('email') if User.objects.filter(email=email).exists(): raise forms.ValidationError('Пользователь с таким email уже зарегистрирован') return email def clean_phone(self): phone = self.cleaned_data.get('phone') if phone: digits_only = ''.join(filter(str.isdigit, phone)) if len(digits_only) < 10: raise forms.ValidationError('Введите корректный номер телефона (минимум 10 цифр)') return phone def clean_full_name(self): full_name = self.cleaned_data.get('full_name') if full_name and len(full_name.strip().split()) < 2: raise forms.ValidationError('Введите полное имя (минимум имя и фамилию)') return full_name def save(self, commit=True): # ★★★ БЕРЕМ РОЛЬ ИЗ ДАННЫХ ★★★ role_name = self.cleaned_data.get('role', 'user') user = super().save(commit=False) user.email = self.cleaned_data['email'] user.full_name = self.cleaned_data['full_name'] user.phone = self.cleaned_data['phone'] # ★★★ НАЗНАЧАЕМ РОЛЬ ★★★ role, _ = Role.objects.get_or_create(name=role_name) user.role = role if commit: user.save() return user class LoginForm(AuthenticationForm): """Форма входа""" username = forms.EmailField(label='Email', widget=forms.EmailInput(attrs={'class': 'form-control'})) password = forms.CharField(label='Пароль', widget=forms.PasswordInput(attrs={'class': 'form-control'})) class MasterClassForm(forms.ModelForm): """Форма для создания/редактирования мастер-класса""" class Meta: model = MasterClass fields = ['title', 'description', 'price', 'category', 'material_file', 'video_link'] widgets = { 'title': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Название мастер-класса'}), 'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 5, 'placeholder': 'Описание'}), 'price': forms.NumberInput(attrs={'class': 'form-control', 'placeholder': 'Цена в рублях', 'step': '0.01'}), 'category': forms.Select(attrs={'class': 'form-control'}), 'material_file': forms.ClearableFileInput(attrs={'class': 'form-control'}), 'video_link': forms.URLInput(attrs={'class': 'form-control', 'placeholder': 'https://youtu.be/...'}), } def clean_price(self): price = self.cleaned_data.get('price') if price is not None and price < 0: raise forms.ValidationError('Цена не может быть отрицательной') if price is not None and price > 1000000: raise forms.ValidationError('Цена не может превышать 1 000 000 ₽') return price def clean_title(self): title = self.cleaned_data.get('title') if title and len(title) < 3: raise forms.ValidationError('Название должно содержать минимум 3 символа') return title class ScheduleForm(forms.ModelForm): """Форма для добавления расписания""" class Meta: model = Schedule fields = ['start_datetime', 'end_datetime', 'max_participants'] widgets = { 'start_datetime': forms.DateTimeInput(attrs={'class': 'form-control', 'type': 'datetime-local'}), 'end_datetime': forms.DateTimeInput(attrs={'class': 'form-control', 'type': 'datetime-local'}), 'max_participants': forms.NumberInput(attrs={'class': 'form-control', 'min': 1}), } def clean(self): cleaned_data = super().clean() start = cleaned_data.get('start_datetime') end = cleaned_data.get('end_datetime') if start and end and start >= end: raise forms.ValidationError('Дата и время окончания должны быть позже даты и времени начала') return cleaned_data class ImageForm(forms.ModelForm): """Форма для добавления изображений""" class Meta: model = Image fields = ['image', 'is_main', 'sort_order'] widgets = { 'image': forms.ClearableFileInput(attrs={'class': 'form-control'}), 'is_main': forms.CheckboxInput(attrs={'class': 'form-check-input'}), 'sort_order': forms.NumberInput(attrs={'class': 'form-control', 'min': 0}), } class CommentForm(forms.ModelForm): """Форма для добавления комментария.""" class Meta: model = Comment fields = ['text'] widgets = { 'text': forms.Textarea(attrs={ 'class': 'form-control', 'rows': 3, 'placeholder': 'Напишите комментарий...', 'style': 'resize: vertical;' }) } labels = { 'text': 'Ваш комментарий' }