Files
redtea 466555ce05 hw3-5
hw3
- Введены типы данных в models.py, сайт переписан под django модели
- DB переведена на PostgreSQL
- Переписан docker compose файл, настроены network и volume
- Добавлена команда генерации рандомных данных в db
hw4
- Добавлены формы login, signup, logout, profile
- Добавлены вопросы и ответы и их модели и формы
hw5
- Добавлена загрузка и отображение аватарок
- Добавлены лайки и дизайки, отметка правильного ответа
2026-05-10 22:56:49 +03:00

173 lines
4.6 KiB
Python

from django import forms
from django.contrib.auth import authenticate
from django.contrib.auth.models import User
from django.contrib.auth.password_validation import validate_password
from django.core.exceptions import ValidationError
import os
from .models import Question, Tag
from .models import Profile
from .models import Answer
def validate_avatar(image):
max_size = 2 * 1024 * 1024
if image.size > max_size:
raise ValidationError("Image too large (max 2MB)")
ext = os.path.splitext(image.name)[1].lower()
allowed_extensions = ['.jpg', '.jpeg', '.png', '.webp', '.ico']
if ext not in allowed_extensions:
raise ValidationError("Unsupported file extension")
class LoginForm(forms.Form):
username = forms.CharField(max_length=150)
password = forms.CharField(widget=forms.PasswordInput)
def clean(self):
cleaned_data = super().clean()
username = cleaned_data.get('username')
password = cleaned_data.get('password')
user = authenticate(username=username, password=password)
if not user:
raise ValidationError("Wrong login or password")
cleaned_data['user'] = user
return cleaned_data
class SignupForm(forms.Form):
username = forms.CharField(max_length=150)
email = forms.EmailField()
nickname = forms.CharField(max_length=100)
password = forms.CharField(widget=forms.PasswordInput)
password_repeat = forms.CharField(widget=forms.PasswordInput)
avatar = forms.ImageField(
required=False,
validators=[validate_avatar]
)
def clean_username(self):
username = self.cleaned_data['username']
if User.objects.filter(username=username).exists():
raise ValidationError("Username already exists")
return username
def clean_email(self):
email = self.cleaned_data['email']
if Profile.objects.filter(email=email).exists():
raise ValidationError("Email already registered")
return email
def clean(self):
cleaned_data = super().clean()
p1 = cleaned_data.get('password')
p2 = cleaned_data.get('password_repeat')
if p1 != p2:
raise ValidationError("Passwords do not match")
validate_password(p1)
return cleaned_data
def save(self):
user = User.objects.create_user(
username=self.cleaned_data['username'],
password=self.cleaned_data['password']
)
Profile.objects.create(
user=user,
email=self.cleaned_data['email'],
nickname=self.cleaned_data['nickname'],
avatar=self.cleaned_data.get('avatar')
)
return user
class ProfileForm(forms.Form):
email = forms.EmailField()
nickname = forms.CharField(max_length=100)
avatar = forms.ImageField(
required=False,
validators=[validate_avatar]
)
def __init__(self, *args, user=None, **kwargs):
super().__init__(*args, **kwargs)
self.user = user
if user:
self.fields['email'].initial = user.profile.email
self.fields['nickname'].initial = user.profile.nickname
def clean_email(self):
email = self.cleaned_data['email']
if Profile.objects.filter(email=email).exclude(user=self.user).exists():
raise ValidationError("Email already used")
return email
def save(self):
profile = self.user.profile
profile.email = self.cleaned_data['email']
profile.nickname = self.cleaned_data['nickname']
if self.cleaned_data.get('avatar'):
profile.avatar = self.cleaned_data['avatar']
profile.save()
class AskForm(forms.ModelForm):
tags = forms.CharField()
class Meta:
model = Question
fields = ['title', 'body']
def clean_tags(self):
tags = self.cleaned_data['tags'].split(',')
tags = [t.strip() for t in tags if t.strip()]
if not tags:
raise ValidationError("Add at least one tag")
return tags
def save(self, user):
question = super().save(commit=False)
question.user = user
question.save()
tags = self.cleaned_data['tags']
for tag_name in tags:
tag, _ = Tag.objects.get_or_create(name=tag_name)
question.tags.add(tag)
return question
class AnswerForm(forms.ModelForm):
class Meta:
model = Answer
fields = ['body']
def save(self, user, question):
answer = super().save(commit=False)
answer.user = user
answer.question = question
answer.save()
return answer