diff --git a/etpgrf_site/blog/migrations/0002_alter_post_is_published_alter_post_post_type_and_more.py b/etpgrf_site/blog/migrations/0002_alter_post_is_published_alter_post_post_type_and_more.py new file mode 100644 index 0000000..f564b87 --- /dev/null +++ b/etpgrf_site/blog/migrations/0002_alter_post_is_published_alter_post_post_type_and_more.py @@ -0,0 +1,47 @@ +# Generated by Django 6.0.1 on 2026-01-26 13:56 + +import django.utils.timezone +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('blog', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='post', + name='is_published', + field=models.BooleanField(db_index=True, default=True, help_text='Снимите галочку, чтобы скрыть публикацию (черновик).', verbose_name='Опубликовано'), + ), + migrations.AlterField( + model_name='post', + name='post_type', + field=models.CharField(choices=[('B', 'Пост в блог'), ('P', 'Страница')], db_index=True, default='B', help_text='Страница доступна по адресу /slug/, Пост — по адресу /blog/slug/', max_length=1, verbose_name='Тип публикации'), + ), + migrations.AlterField( + model_name='post', + name='published_at', + field=models.DateTimeField(db_index=True, default=django.utils.timezone.now, help_text='Дата, которая будет отображаться в блоге. Можно запланировать на будущее.', verbose_name='Дата публикации'), + ), + migrations.AlterField( + model_name='post', + name='seo_keywords', + field=models.CharField(blank=True, help_text='Ключевые слова через запятую (meta keywords). Сейчас почти не используется поисковиками,но может пригодиться.', max_length=255, verbose_name='SEO Keywords'), + ), + migrations.AlterField( + model_name='post', + name='seo_title', + field=models.CharField(blank=True, help_text='Заголовок для поисковиков (<title>). Если пусто, используется основной заголовок.', max_length=255, verbose_name='SEO Title'), + ), + migrations.AddIndex( + model_name='post', + index=models.Index(fields=['post_type', 'is_published', '-published_at'], name='blog_post_idx'), + ), + migrations.AddIndex( + model_name='post', + index=models.Index(fields=['post_type', 'slug'], name='blog_page_slug_idx'), + ), + ] diff --git a/etpgrf_site/blog/models.py b/etpgrf_site/blog/models.py index 2572abb..ee93ae2 100644 --- a/etpgrf_site/blog/models.py +++ b/etpgrf_site/blog/models.py @@ -27,17 +27,20 @@ class Post(models.Model): max_length=1, choices=PostType.choices, default=PostType.BLOG, + db_index=True, help_text="Страница доступна по адресу /slug/, Пост — по адресу /blog/slug/" ) is_published = models.BooleanField( verbose_name="Опубликовано", default=True, + db_index=True, help_text="Снимите галочку, чтобы скрыть публикацию (черновик)." ) published_at = models.DateTimeField( verbose_name="Дата публикации", default=timezone.now, + db_index=True, help_text="Дата, которая будет отображаться в блоге. Можно запланировать на будущее." ) @@ -83,6 +86,12 @@ class Post(models.Model): verbose_name = "Публикация" verbose_name_plural = "Публикации" ordering = ['-published_at'] + indexes = [ + # Индекс для быстрого поиска и сортировки постов блога + models.Index(fields=['post_type', 'is_published', '-published_at'], name='blog_post_idx'), + # Индекс для быстрых страниц (если post_type='P') + models.Index(fields=['post_type', 'slug'], name='blog_page_slug_idx'), + ] def __str__(self): return self.title diff --git a/etpgrf_site/etpgrf_site/settings.py b/etpgrf_site/etpgrf_site/settings.py index b69c2e1..98b4edb 100644 --- a/etpgrf_site/etpgrf_site/settings.py +++ b/etpgrf_site/etpgrf_site/settings.py @@ -35,6 +35,7 @@ INSTALLED_APPS = [ 'django.contrib.messages', 'django.contrib.staticfiles', 'typograph', + 'blog', # Наше новое приложение ] MIDDLEWARE = [ @@ -53,7 +54,7 @@ ROOT_URLCONF = 'etpgrf_site.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], + 'DIRS': [], # Шаблоны ищем внутри приложений (APP_DIRS=True) 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [