/
nmktth
/
web-development-sem-4
Обзор
Документация
Войти
/
nmktth
/
web-development-sem-4
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
realty/models.py
260 строк
9 KB
artem
feat: complete Realty frontend, accessibility and lab reports
02 июн 2026, 08:46
02 июн 2026, 08:46
873b76d
Код
Авторство
О чём код?
from django.db import models from django.contrib.auth.models import AbstractUser from django.utils import timezone from datetime import timedelta from django.urls import reverse # Create your models here. class ActiveAdsManager(models.Manager): # Возвращает только актуальные объявления def get_queryset(self): return super().get_queryset().filter(is_active=True) class User(AbstractUser): ROLE_CHOICES = [ ('admin', 'Админ'), ('user', 'Пользователь') ] favorite_ads = models.ManyToManyField( 'Advertisement', through='Favorite', through_fields=('user', 'advertisement'), related_name='liked_by' ) middle_name = models.CharField("Отчество", max_length=150, blank=True) email = models.EmailField("Электронная почта", unique=True) role = models.CharField( "Роль", max_length=20, choices=ROLE_CHOICES, default='user') about = models.TextField("О себе", blank=True, null=True) avatar = models.ImageField( "Аватар", upload_to='users/avatars/', blank=True, null=True ) USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['username', 'first_name', 'last_name'] def is_newbie(self): # Для новичков, чтобы добавить ограничения return self.date_joined >= timezone.now() - timedelta(hours=6) class Meta: verbose_name = "Пользователь" verbose_name_plural = "Пользователи" ordering = ['-date_joined'] def __str__(self): return f"{self.last_name} {self.first_name}".strip() or self.email class Advertisement(models.Model): TYPES = [('room', 'Комната'), ('flat', 'Квартира'), ('house', 'Дом'), ('bed', 'Койко-место')] DEALS = [('rent_out', 'Сдаю'), ('look_for', 'Ищу')] user = models.ForeignKey( User, on_delete=models.CASCADE, verbose_name="Автор", related_name="ads") title = models.CharField("Заголовок", max_length=255) description = models.TextField("Описание") type = models.CharField("Тип жилья", max_length=20, choices=TYPES) deal_type = models.CharField("Тип сделки", max_length=20, choices=DEALS) price = models.DecimalField("Цена", max_digits=10, decimal_places=2) deposit = models.DecimalField( "Залог", max_digits=10, decimal_places=2, blank=True, null=True) metro = models.CharField("Метро", max_length=100, blank=True, null=True) address = models.CharField("Адрес", max_length=255) city = models.CharField("Город", max_length=100) is_active = models.BooleanField("Активно", default=True) views_count = models.PositiveIntegerField("Просмотры", default=0) image = models.ImageField( "Фото жилья", upload_to='ads/images/%Y/%m/%d/', blank=True, null=True ) contract_template = models.FileField( "Образец договора", upload_to='ads/contracts/', blank=True, null=True ) video_url = models.URLField( max_length=512, blank=True, null=True ) objects = models.Manager() active_objects = ActiveAdsManager() def get_absolute_url(self): return reverse('ad_detail', args=[str(self.id)]) # 3 лаба timezone с примерами created_at = models.DateTimeField("Дата создания", auto_now_add=True) updated_at = models.DateTimeField("Дата обновления", auto_now=True) def is_new(self): # Для отображения объявления с пометкой "Новое" return self.created_at >= timezone.now() - timedelta(days=3) def is_boosted(self): # Количество времени сколько объявление отоброжается в топе return self.created_at >= timezone.now() - timedelta(hours=1) def needs_confirmation(self): # Срок жизни объявления (требуем подтверждение актуальности) return self.updated_at < timezone.now() - timedelta(days=14) class Meta: verbose_name = "Объявление" verbose_name_plural = "Объявления" ordering = ['-created_at'] def __str__(self): return f"{self.title} ({self.city})" class Favorite(models.Model): user = models.ForeignKey( User, on_delete=models.CASCADE, verbose_name="Пользователь", related_name="favorites") advertisement = models.ForeignKey( Advertisement, on_delete=models.CASCADE, verbose_name="Объявление") created_at = models.DateTimeField("Добавлено", auto_now_add=True) class Meta: verbose_name = "Избранное" verbose_name_plural = "Избранное" unique_together = ('user', 'advertisement') ordering = ['-created_at'] def __str__(self): return f"{self.user.email} -> {self.advertisement.title}" class Chat(models.Model): user_1 = models.ForeignKey( User, on_delete=models.CASCADE, related_name="chats_initiated", verbose_name="Инициатор") user_2 = models.ForeignKey( User, on_delete=models.CASCADE, related_name="chats_received", verbose_name="Ответчик") advertisement = models.ForeignKey( 'Advertisement', on_delete=models.CASCADE, null=True, blank=True, verbose_name="Объявление" ) created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField("Создан", auto_now_add=True) class Meta: verbose_name = "Чат" verbose_name_plural = "Чаты" ordering = ['-created_at'] def __str__(self): return f"Чат по объявлению #{self.advertisement_id}" class Message(models.Model): chat = models.ForeignKey( Chat, on_delete=models.CASCADE, verbose_name="Чат", related_name="messages") sender = models.ForeignKey( User, on_delete=models.CASCADE, verbose_name="Отправитель") text = models.TextField("Текст сообщения") sent_at = models.DateTimeField("Отправлено", auto_now_add=True) is_read = models.BooleanField("Прочитано", default=False) class Meta: verbose_name = "Сообщение" verbose_name_plural = "Сообщения" ordering = ['sent_at'] def __str__(self): return f"От {self.sender.email} в {self.sent_at}" class NeighborRequest(models.Model): user = models.ForeignKey( User, on_delete=models.CASCADE, verbose_name="Пользователь", related_name="neighbor_requests") city = models.CharField("Город", max_length=100) description = models.TextField("О себе и партнере") looking_for_apartment = models.BooleanField("Ищет квартиру", default=True) is_active = models.BooleanField("Активна", default=True) created_at = models.DateTimeField("Дата публикации", auto_now_add=True) def is_expired(self): # Время спустя которое заявка становится неактуальной (удаляется) return self.created_at < timezone.now() - timedelta(days=3) class Meta: verbose_name = "Заявка соседа" verbose_name_plural = "Заявки соседей" ordering = ['-created_at'] def __str__(self): return f"Сосед в {self.city} ({self.user.email})" class Complaint(models.Model): STATUSES = [('pending', 'Ожидает'), ('resolved', 'Решено'), ('rejected', 'Отклонено')] complainant = models.ForeignKey( User, on_delete=models.CASCADE, verbose_name="Кто жалуется", related_name="complaints") content_type = models.CharField("Тип контента", max_length=50) content_id = models.PositiveIntegerField("ID объекта") reason = models.TextField("Причина") status = models.CharField("Статус", max_length=20, choices=STATUSES, default='pending') created_at = models.DateTimeField("Дата", auto_now_add=True) class Meta: verbose_name = "Жалоба" verbose_name_plural = "Жалобы" ordering = ['-created_at'] def __str__(self): return f"Жалоба от {self.complainant.email} ({self.status})" class News(models.Model): title = models.CharField("Заголовок", max_length=255) content = models.TextField("Содержание") image = models.ImageField( "Изображение", upload_to='news/', blank=True, null=True) created_at = models.DateTimeField("Дата публикации", auto_now_add=True) class Meta: verbose_name = "Новость" verbose_name_plural = "Новости" ordering = ['-created_at'] def __str__(self): return self.title