Site/programmer/models.py

205 lines
9.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from django.contrib.auth.models import User
from django.db import models
from django.urls import reverse
from django.utils import timezone
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from django.core.cache import cache
from .utils.email_notifications import send_callback_notification
class Recall(models.Model):
title = models.CharField(max_length=255, verbose_name='Организация')
content = models.TextField(blank=True, verbose_name='Отзыв')
scan = models.ImageField(upload_to="scan/%Y/%m/%d/", verbose_name='Фото')
time_create = models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')
time_update = models.DateTimeField(auto_now=True, verbose_name='Дата изменения')
is_published = models.BooleanField(default=True, verbose_name='Опубликован')
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post', kwargs={'post_id': self.pk})
class Meta:
verbose_name = 'Отзыв'
verbose_name_plural = 'Отзывы'
ordering = ['time_create', 'title']
def get_seo_title(self):
return f"Отзыв от {self.title} | Программист 1С"
def get_seo_description(self):
if self.content:
clean_content = self.content[:160].replace('\n', ' ').strip()
return f"Отзыв о работе программиста 1С от {self.title}. {clean_content}..."
return f"Отзыв клиента {self.title} о работе программиста 1С Николая Сердюк"
class Competence(models.Model):
title = models.CharField(max_length=255, verbose_name='Программист')
content = models.TextField(blank=True, verbose_name='Компетенция')
photo = models.ImageField(upload_to="photos/%Y/%m/%d/", verbose_name='Фото')
time_create = models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')
time_update = models.DateTimeField(auto_now=True, verbose_name='Дата изменения')
is_published = models.BooleanField(default=True, verbose_name='Опубликован')
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post', kwargs={'post_id': self.pk})
class Meta:
verbose_name = 'Компетенция'
verbose_name_plural = 'Компетенции'
ordering = ['time_create', 'title']
class Solution(models.Model):
title = models.CharField(max_length=255, verbose_name='Наименование')
description = models.TextField(blank=True, verbose_name='Описание')
implementation = models.TextField(blank=True, verbose_name='Реализация')
closing = models.TextField(blank=True, verbose_name='Заключение')
time_create = models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')
time_update = models.DateTimeField(auto_now=True, verbose_name='Дата изменения')
is_published = models.BooleanField(default=True, verbose_name='Опубликован')
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post', kwargs={'post_id': self.pk})
class Meta:
verbose_name = 'Проекты'
verbose_name_plural = 'Проекты'
ordering = ['time_create', 'title']
def get_seo_title(self):
"""Генерирует SEO-заголовок для проекта"""
return f"Проект: {self.title} | Автоматизация 1С"
def get_seo_description(self):
"""Генерирует SEO-описание для проекта"""
if self.description:
clean_desc = self.description[:160].replace('\n', ' ').strip()
return f"Проект автоматизации: {self.title}. {clean_desc}..."
return f"Реализация проекта {self.title} - программист 1С Николай Сердюк"
def get_meta_keywords(self):
"""Автоматические ключевые слова для проекта"""
base_keywords = ["проект 1С", "автоматизация 1С", "внедрение 1С"]
title_words = self.title.lower().split()
return base_keywords + title_words
class Home(models.Model):
title = models.CharField(max_length=255, verbose_name='Наименование')
content = models.TextField(blank=True, verbose_name='Статья')
home_image = models.ImageField(upload_to="home_image/%Y/%m/%d/", verbose_name='Фото')
time_create = models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')
time_update = models.DateTimeField(auto_now=True, verbose_name='Дата изменения')
is_published = models.BooleanField(default=True, verbose_name='Опубликован')
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post', kwargs={'post_id': self.pk})
class Meta:
verbose_name = 'Главная страница'
verbose_name_plural = 'Главная страница'
ordering = ['time_create', 'title']
class CallbackRequest(models.Model):
name = models.CharField(max_length=100, verbose_name='Имя')
phone = models.CharField(max_length=20, verbose_name='Телефон')
email = models.EmailField(blank=True, null=True, verbose_name='Электронная почта') # Сделать необязательным
question = models.TextField(blank=True, verbose_name='Ваш вопрос') # Сделать необязательным
time_create = models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')
is_processed = models.BooleanField(default=False, verbose_name='Обработано')
is_read = models.BooleanField(default=False, verbose_name='Прочитано')
notification_sent = models.BooleanField(default=False, verbose_name='Уведомление отправлено')
def __str__(self):
return f"{self.name} - {self.phone}"
class Meta:
verbose_name = 'Заявка на звонок'
verbose_name_plural = 'Заявки на звонок'
ordering = ['-time_create']
# Сигнал для отправки уведомления при создании заявки
@receiver(post_save, sender=CallbackRequest)
def send_callback_email_notification(sender, instance, created, **kwargs):
if created and not instance.notification_sent:
# Отправляем email уведомление
success = send_callback_notification(instance)
if success:
instance.notification_sent = True
# Сохраняем без повторного вызова сигнала
sender.objects.filter(pk=instance.pk).update(notification_sent=True)
class PageView(models.Model):
url = models.CharField(max_length=500)
timestamp = models.DateTimeField(default=timezone.now)
ip_address = models.GenericIPAddressField()
user_agent = models.TextField(blank=True)
referer = models.CharField(max_length=500, blank=True)
class Meta:
indexes = [
models.Index(fields=['url', 'timestamp']),
models.Index(fields=['timestamp']),
]
class Visitor(models.Model):
ip_address = models.GenericIPAddressField()
first_visit = models.DateTimeField(default=timezone.now)
last_visit = models.DateTimeField(default=timezone.now)
visit_count = models.IntegerField(default=1)
class Meta:
indexes = [
models.Index(fields=['ip_address']),
]
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, verbose_name='Пользователь')
phone = models.CharField(max_length=20, blank=True, verbose_name='Телефон')
company = models.CharField(max_length=255, blank=True, verbose_name='Компания')
specialization = models.CharField(max_length=100, blank=True, verbose_name='Специализация')
avatar = models.ImageField(upload_to='avatars/%Y/%m/%d/', blank=True, verbose_name='Аватар')
email_notifications = models.BooleanField(default=True, verbose_name='Получать уведомления')
def __str__(self):
return f'Профиль {self.user.username}'
class Meta:
verbose_name = 'Профиль'
verbose_name_plural = 'Профили'
@receiver(post_save, sender=User)
def create_or_save_user_profile(sender, instance, **kwargs):
# Получаем или создаём профиль, затем сохраняем
profile, created = Profile.objects.get_or_create(user=instance)
profile.save()
@receiver([post_save, post_delete], sender=Home)
@receiver([post_save, post_delete], sender=Solution)
@receiver([post_save, post_delete], sender=Competence)
@receiver([post_save, post_delete], sender=Recall)
def clear_sitemap_cache(sender, **kwargs):
"""Очищаем кэш sitemap при изменении контента"""
cache.delete('sitemap_cache')