<<<<<<< HEAD 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'] 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'] 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']), ] @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') ======= 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']), ] @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') >>>>>>> master