diff --git a/GeneralApp/admin.py b/GeneralApp/admin.py index 1dd926a..1c55523 100644 --- a/GeneralApp/admin.py +++ b/GeneralApp/admin.py @@ -104,12 +104,12 @@ class Admin_StaticPage(SuperModelAdmin, Admin_Trans_BaseModelViewPage): 'order', ) }), - ('SEO', { - 'classes': ['wide', 'collapse'], - 'fields': ( - 'seo_title', 'seo_description', 'seo_keywords', 'seo_text', - ) - }), + # ('SEO', { + # 'classes': ['wide', 'collapse'], + # 'fields': ( + # 'seo_title', 'seo_description', 'seo_keywords', 'seo_text', + # ) + # }), ] diff --git a/GeneralApp/migrations/0022_alter_office_work_time_from_and_more.py b/GeneralApp/migrations/0022_alter_office_work_time_from_and_more.py new file mode 100644 index 0000000..e302b36 --- /dev/null +++ b/GeneralApp/migrations/0022_alter_office_work_time_from_and_more.py @@ -0,0 +1,44 @@ +# Generated by Django 4.2.7 on 2023-12-10 14:48 + +import datetime +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('GeneralApp', '0021_alter_office_worktime_alter_office_worktime_en_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='office', + name='work_time_from', + field=models.TimeField(default=datetime.datetime(2023, 12, 10, 9, 0), verbose_name='Время работы с'), + ), + migrations.AlterField( + model_name='office', + name='work_time_from_en', + field=models.TimeField(default=datetime.datetime(2023, 12, 10, 9, 0), null=True, verbose_name='Время работы с'), + ), + migrations.AlterField( + model_name='office', + name='work_time_from_ru', + field=models.TimeField(default=datetime.datetime(2023, 12, 10, 9, 0), null=True, verbose_name='Время работы с'), + ), + migrations.AlterField( + model_name='office', + name='work_time_to', + field=models.TimeField(default=datetime.datetime(2023, 12, 10, 18, 0), verbose_name='Время работы до'), + ), + migrations.AlterField( + model_name='office', + name='work_time_to_en', + field=models.TimeField(default=datetime.datetime(2023, 12, 10, 18, 0), null=True, verbose_name='Время работы до'), + ), + migrations.AlterField( + model_name='office', + name='work_time_to_ru', + field=models.TimeField(default=datetime.datetime(2023, 12, 10, 18, 0), null=True, verbose_name='Время работы до'), + ), + ] diff --git a/PortfolioApp/admin.py b/PortfolioApp/admin.py index 8c38f3f..3301439 100644 --- a/PortfolioApp/admin.py +++ b/PortfolioApp/admin.py @@ -1,3 +1,85 @@ +from sets.admin import * +from .models import * from django.contrib import admin +from django.forms import widgets +# from nested_inline.admin import NestedStackedInline, NestedTabularInline, NestedModelAdmin, NestedInline +from super_inlines.admin import SuperInlineModelAdmin, SuperModelAdmin +from GeneralApp.admin import Admin_StackedInline_Block +from SlidesApp.admin import Admin_StackedInline_Slide +from django.utils.translation import gettext as _ -# Register your models here. + +class Admin_Project(SuperModelAdmin, Admin_Trans_BaseModelViewPage): + from ServicesApp.admin import Admin_StackedInline_BlockPluginPresentation + + def services_str(self, obj): + services = obj.get_services() + if services: + return " / ".join(services.values_list("name", flat=True)) + return '-' + services_str.short_description = _("Услуги") + services_str.allow_tags = True + + fieldsets = [ + (None, { + 'classes': ['wide'], + 'fields': ( + 'name', + 'url', + 'title', + 'description', + 'services', + # 'text', + 'picture', + 'order', + ) + }), + # (_('Дополнительно'), { + # 'classes': ['wide', 'collapse'], + # 'fields': ( + # 'FAQ_title', + # ) + # }), + # ('SEO', { + # 'classes': ['wide', 'collapse'], + # 'fields': ( + # 'seo_title', 'seo_description', 'seo_keywords', 'seo_text', + # ) + # }), + ] + + + list_display = [ + 'image_thumb', + 'id', + 'name', 'url', + # 'title', + 'order', + 'services_str', + 'createDT', 'modifiedDT' + ] + + prepopulated_fields = {"url": ("name_en",)} + + list_display_links = ['id', 'name', 'image_thumb'] + list_editable = ['order'] + + list_filter = ['modifiedDT', 'createDT'] + search_fields = ['name', 'title'] + filter_horizontal = ['services'] + + inlines = [ + # Admin_StackedInline_Slide, + Admin_StackedInline_BlockPluginPresentation, + Admin_StackedInline_Block, + # AdminStacked_FAQitem, + ] + + def has_delete_permission(self, request, obj=None): + if request.user.is_superuser: + return True + + if obj.url in ('main', 'spec_technics', 'works'): + return False + +admin.site.register(Project, Admin_Project) \ No newline at end of file diff --git a/PortfolioApp/migrations/0001_initial.py b/PortfolioApp/migrations/0001_initial.py new file mode 100644 index 0000000..66b7015 --- /dev/null +++ b/PortfolioApp/migrations/0001_initial.py @@ -0,0 +1,62 @@ +# Generated by Django 4.2.7 on 2023-12-10 14:48 + +import BaseModels.base_models +import ckeditor_uploader.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('ServicesApp', '0007_section_page_scheme'), + ] + + operations = [ + migrations.CreateModel( + name='Project', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')), + ('name_ru', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')), + ('name_en', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')), + ('name_plural', models.TextField(blank=True, null=True, verbose_name='Название (множественное число)')), + ('order', models.IntegerField(blank=True, null=True, verbose_name='Очередность отображения')), + ('createDT', models.DateTimeField(auto_now_add=True, verbose_name='Дата и время создания')), + ('modifiedDT', models.DateTimeField(blank=True, null=True, verbose_name='Дата и время последнего изменения')), + ('enable', models.BooleanField(db_index=True, default=True, verbose_name='Включено')), + ('json_data', models.JSONField(blank=True, default=dict, verbose_name='Дополнительные данные')), + ('url', models.TextField(help_text='можно изменить адрес страницы (!!! ВНИМАНИЕ !!! поисковые системы потеряют страницу и найдут лишь спустя неделю...месяц)', unique=True, verbose_name='URL привязанной страницы')), + ('title', models.TextField(blank=True, null=True, verbose_name='Заголовок')), + ('title_ru', models.TextField(blank=True, null=True, verbose_name='Заголовок')), + ('title_en', models.TextField(blank=True, null=True, verbose_name='Заголовок')), + ('description', ckeditor_uploader.fields.RichTextUploadingField(blank=True, help_text='краткое описание страницы (до 240 символов)', null=True, verbose_name='Краткое описание')), + ('description_ru', ckeditor_uploader.fields.RichTextUploadingField(blank=True, help_text='краткое описание страницы (до 240 символов)', null=True, verbose_name='Краткое описание')), + ('description_en', ckeditor_uploader.fields.RichTextUploadingField(blank=True, help_text='краткое описание страницы (до 240 символов)', null=True, verbose_name='Краткое описание')), + ('text', ckeditor_uploader.fields.RichTextUploadingField(blank=True, null=True, verbose_name='Полное описание')), + ('text_ru', ckeditor_uploader.fields.RichTextUploadingField(blank=True, null=True, verbose_name='Полное описание')), + ('text_en', ckeditor_uploader.fields.RichTextUploadingField(blank=True, null=True, verbose_name='Полное описание')), + ('picture', models.FileField(blank=True, null=True, upload_to='uploads/', validators=[BaseModels.base_models.validate_file_extension], verbose_name='Картинка')), + ('visible', models.BooleanField(default=True, verbose_name='Отображать')), + ('seo_title', models.CharField(blank=True, max_length=250, null=True, verbose_name='Title (80 знаков)')), + ('seo_title_ru', models.CharField(blank=True, max_length=250, null=True, verbose_name='Title (80 знаков)')), + ('seo_title_en', models.CharField(blank=True, max_length=250, null=True, verbose_name='Title (80 знаков)')), + ('seo_description', models.CharField(blank=True, max_length=250, null=True, verbose_name='Description (150 знаков)')), + ('seo_description_ru', models.CharField(blank=True, max_length=250, null=True, verbose_name='Description (150 знаков)')), + ('seo_description_en', models.CharField(blank=True, max_length=250, null=True, verbose_name='Description (150 знаков)')), + ('seo_keywords', models.CharField(blank=True, max_length=250, null=True, verbose_name='Keywords (200 знаков)')), + ('seo_text', ckeditor_uploader.fields.RichTextUploadingField(blank=True, null=True, verbose_name='Текст SEO статьи')), + ('seo_text_ru', ckeditor_uploader.fields.RichTextUploadingField(blank=True, null=True, verbose_name='Текст SEO статьи')), + ('seo_text_en', ckeditor_uploader.fields.RichTextUploadingField(blank=True, null=True, verbose_name='Текст SEO статьи')), + ('FAQ_title', models.CharField(blank=True, max_length=250, null=True, verbose_name='FAQ Заголовок')), + ('FAQ_title_ru', models.CharField(blank=True, max_length=250, null=True, verbose_name='FAQ Заголовок')), + ('FAQ_title_en', models.CharField(blank=True, max_length=250, null=True, verbose_name='FAQ Заголовок')), + ('services', models.ManyToManyField(blank=True, related_name='rel_projects_for_service', to='ServicesApp.service', verbose_name='Услуги которые использовались для реализации')), + ], + options={ + 'verbose_name': 'Проект', + 'verbose_name_plural': 'Проекты', + }, + ), + ] diff --git a/PortfolioApp/models.py b/PortfolioApp/models.py index 41b2185..a659483 100644 --- a/PortfolioApp/models.py +++ b/PortfolioApp/models.py @@ -9,8 +9,17 @@ from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.fields import GenericRelation from colorfield.fields import ColorField -class Project(BaseModelViewPage): +class Project(BaseModelViewPage): + from ServicesApp.models import Service + services = models.ManyToManyField( + Service, verbose_name=_('Услуги которые использовались для реализации'), + blank=True, related_name='rel_projects_for_service' + ) + + def get_services(self): + services = self.services.filter(enable=True).order_by('order') + return services class Meta: verbose_name = _('Проект') diff --git a/PortfolioApp/translation.py b/PortfolioApp/translation.py new file mode 100644 index 0000000..e16bf2f --- /dev/null +++ b/PortfolioApp/translation.py @@ -0,0 +1,10 @@ +from modeltranslation.translator import translator, TranslationOptions +from .models import * + + +class Project_TranslationOptions(TranslationOptions): + fields = ( + 'name', 'description', 'text', 'title', 'FAQ_title', 'seo_title', 'seo_description', 'seo_text' + ) +translator.register(Project, Project_TranslationOptions) + diff --git a/ServicesApp/admin.py b/ServicesApp/admin.py index 0759bff..adc5293 100644 --- a/ServicesApp/admin.py +++ b/ServicesApp/admin.py @@ -58,18 +58,18 @@ class Admin_Section(SuperModelAdmin, Admin_Trans_BaseModelViewPage): 'order', ) }), - (_('Дополнительно'), { - 'classes': ['wide', 'collapse'], - 'fields': ( - 'FAQ_title', - ) - }), - ('SEO', { - 'classes': ['wide', 'collapse'], - 'fields': ( - 'seo_title', 'seo_description', 'seo_keywords', 'seo_text', - ) - }), + # (_('Дополнительно'), { + # 'classes': ['wide', 'collapse'], + # 'fields': ( + # 'FAQ_title', + # ) + # }), + # ('SEO', { + # 'classes': ['wide', 'collapse'], + # 'fields': ( + # 'seo_title', 'seo_description', 'seo_keywords', 'seo_text', + # ) + # }), ] @@ -124,12 +124,12 @@ class Admin_Service(SuperModelAdmin, Admin_Trans_BaseModelViewPage): 'order', ) }), - ('SEO', { - 'classes': ['wide', 'collapse'], - 'fields': ( - 'seo_title', 'seo_description', 'seo_keywords', 'seo_text', - ) - }), + # ('SEO', { + # 'classes': ['wide', 'collapse'], + # 'fields': ( + # 'seo_title', 'seo_description', 'seo_keywords', 'seo_text', + # ) + # }), ] diff --git a/pAerBim/settings.py b/pAerBim/settings.py index 091cb92..cf37184 100644 --- a/pAerBim/settings.py +++ b/pAerBim/settings.py @@ -53,6 +53,7 @@ INSTALLED_APPS = [ 'GeneralApp', 'ServicesApp', 'SlidesApp', + 'PortfolioApp', ] MIDDLEWARE = [