hw3 - Введены типы данных в models.py, сайт переписан под django модели - DB переведена на PostgreSQL - Переписан docker compose файл, настроены network и volume - Добавлена команда генерации рандомных данных в db hw4 - Добавлены формы login, signup, logout, profile - Добавлены вопросы и ответы и их модели и формы hw5 - Добавлена загрузка и отображение аватарок - Добавлены лайки и дизайки, отметка правильного ответа
173 lines
4.6 KiB
Python
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 |