/
Codename-Nik
/
WebApp
Обзор
Документация
Войти
/
Codename-Nik
/
WebApp
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
backend/api/models.py
136 строк
5 KB
Nikolay Pokhodnya
first commit
03 ноя 2025, 19:47
03 ноя 2025, 19:47
a9fbdee
Код
Авторство
О чём код?
from django.db import models from django.contrib.auth.models import AbstractUser from django.utils.crypto import get_random_string from django.core.mail import send_mail from django.conf import settings # Create your models here. class CustomUser(AbstractUser): email = models.EmailField(unique=True) bio = models.TextField(max_length=500, blank=True, default='') avatar = models.ImageField(upload_to='avatars/', null=True, blank=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return self.username class Project(models.Model): name = models.CharField(max_length=100) description = models.TextField(blank=True, default='') owner = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='owned_projects') members = models.ManyToManyField(CustomUser, related_name='projects', blank=True) color = models.CharField(max_length=7, default='#1976D2') created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: ordering = ['-created_at'] def __str__(self): return self.name class Task(models.Model): STATUS_CHOICES = [ ('todo', 'To Do'), ('in_progress', 'In Progress'), ('review', 'Review'), ('done', 'Done'), ] PRIORITY_CHOICES = [ ('low', 'Low'), ('medium', 'Medium'), ('high', 'High'), ('urgent', 'Urgent'), ] title = models.CharField(max_length=200) description = models.TextField(blank=True, default='') status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='todo') priority = models.CharField(max_length=20, choices=PRIORITY_CHOICES, default='medium') due_date = models.DateTimeField(null=True, blank=True) project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name='tasks', null=True, blank=True) assigned_to = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, null=True, blank=True, related_name='assigned_tasks') created_by = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='created_tasks') created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: ordering = ['-created_at'] indexes = [ models.Index(fields=['status', 'priority']), models.Index(fields=['due_date']), ] def __str__(self): return self.title class Comment(models.Model): task = models.ForeignKey(Task, on_delete=models.CASCADE, related_name='comments') author = models.ForeignKey(CustomUser, on_delete=models.CASCADE) content = models.TextField(default='') created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: ordering = ['created_at'] def __str__(self): return f"Comment by {self.author} on {self.task}" class Invitation(models.Model): STATUS_CHOICES = [ ('pending', 'Pending'), ('accepted', 'Accepted'), ('declined', 'Declined'), ('expired', 'Expired'), ] email = models.EmailField() token = models.CharField(max_length=50, unique=True) project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name='invitations') invited_by = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='sent_invitations') invited_user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, null=True, blank=True, related_name='received_invitations') status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending') created_at = models.DateTimeField(auto_now_add=True) expires_at = models.DateTimeField() class Meta: ordering = ['-created_at'] unique_together = ['email', 'project'] def save(self, *args, **kwargs): if not self.token: self.token = get_random_string(50) if not self.expires_at: from django.utils.timezone import now, timedelta self.expires_at = now() + timedelta(days=7) super().save(*args, **kwargs) def is_expired(self): from django.utils.timezone import now return now() > self.expires_at def __str__(self): return f"Invitation for {self.email} to {self.project.name}" def send_invitation_email(invitation): """Отправка email с приглашением""" subject = f'Приглашение в проект {invitation.project.name}' message = f''' Вы приглашены в проект "{invitation.project.name}" пользователем {invitation.invited_by.get_full_name()}. Для принятия приглашения перейдите по ссылке: http://localhost:8080/invitations/accept/{invitation.token}/ Ссылка действительна до {invitation.expires_at.strftime("%d.%m.%Y %H:%M")} ''' send_mail( subject, message, settings.DEFAULT_FROM_EMAIL, [invitation.email], fail_silently=False, )