Files
smartsoltech_site/smartsoltech/web/admin.py

322 lines
12 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 import admin
from .models import (
Service, Project, Client, Order, Review, BlogPost,
Category, ServiceRequest, AboutPage, FooterSettings, TeamMember,
PortfolioItem, PrivacyPolicy, TermsOfUse, NewsArticle, CareerVacancy,
SiteSettings, PortfolioImage, ContactSettings
)
from .forms import ProjectForm
@admin.register(Service)
class ServiceAdmin(admin.ModelAdmin):
list_display = ('name', 'category', 'price')
search_fields = ('name', 'category')
@admin.register(Project)
class ProjectAdmin(admin.ModelAdmin):
form = ProjectForm
list_display = ('name', 'client','service', 'status', 'order', 'description')
list_filter = ('name', 'client','service', 'status', 'order')
search_fields = ('name', 'client','service', 'status', 'order', 'client__first_name', 'client__last_name')
@admin.register(Client)
class ClientAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name', 'email', 'phone_number')
search_fields = ('first_name', 'last_name', 'email')
@admin.register(Order)
class OrderAdmin(admin.ModelAdmin):
list_display = ('id', 'service', 'client', 'client__email', 'client__phone_number', 'status')
list_filter = ('status','client', 'order_date')
search_fields = ('client__first_name', 'service__name','status','client', 'order_date')
@admin.register(Review)
class ReviewAdmin(admin.ModelAdmin):
list_display = ('client', 'service', 'rating', 'review_date')
list_filter = ('rating',)
search_fields = ('client__first_name', 'service__name')
@admin.register(BlogPost)
class BlogPostAdmin(admin.ModelAdmin):
list_display = ('title', 'status', 'author', 'published_date')
list_filter = ('status', 'published_date')
search_fields = ('title', 'excerpt', 'author__username')
prepopulated_fields = {'slug': ('title',)}
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = ('name','description')
search_fields = ('name',)
class PortfolioImageInline(admin.TabularInline):
model = PortfolioImage
extra = 3
fields = ('image', 'caption', 'order')
verbose_name = 'Дополнительное изображение'
verbose_name_plural = 'Галерея изображений'
@admin.register(PortfolioItem)
class PortfolioItemAdmin(admin.ModelAdmin):
list_display = ('title', 'client_name', 'completion_date', 'featured', 'is_active', 'gallery_count', 'categories_display')
list_filter = ('featured', 'is_active', 'completion_date', 'categories')
search_fields = ('title', 'client_name', 'description')
prepopulated_fields = {'slug': ('title',)}
filter_horizontal = ('categories',)
inlines = [PortfolioImageInline]
def gallery_count(self, obj):
return obj.gallery_images.count()
gallery_count.short_description = 'Фото в галерее' # type: ignore
def categories_display(self, obj):
return ", ".join([cat.name for cat in obj.categories.all()[:3]])
categories_display.short_description = 'Категории' # type: ignore
@admin.register(NewsArticle)
class NewsArticleAdmin(admin.ModelAdmin):
list_display = ('title', 'is_published', 'published_date', 'created_at')
list_filter = ('is_published', 'published_date', 'created_at')
search_fields = ('title', 'excerpt')
prepopulated_fields = {'slug': ('title',)}
@admin.register(CareerVacancy)
class CareerVacancyAdmin(admin.ModelAdmin):
list_display = ('title', 'location', 'employment_type', 'is_active', 'posted_at')
list_filter = ('employment_type', 'is_active', 'posted_at')
search_fields = ('title', 'location')
prepopulated_fields = {'slug': ('title',)}
@admin.register(PrivacyPolicy)
class PrivacyPolicyAdmin(admin.ModelAdmin):
list_display = ('version', 'effective_date', 'is_active')
list_filter = ('is_active', 'effective_date')
search_fields = ('version',)
@admin.register(TermsOfUse)
class TermsOfUseAdmin(admin.ModelAdmin):
list_display = ('version', 'effective_date', 'is_active')
list_filter = ('is_active', 'effective_date')
search_fields = ('version',)
@admin.register(ServiceRequest)
class ServiceRequestAdmin(admin.ModelAdmin):
list_display = ('service','token', 'client', 'created_at')
search_fields = ('service','token', 'client')
list_filter = ('service','token','client')
@admin.register(AboutPage)
class AboutPageAdmin(admin.ModelAdmin):
list_display = ('hero_title', 'is_active', 'updated_at')
list_filter = ('is_active', 'updated_at')
search_fields = ('hero_title', 'mission_title', 'vision_title')
fieldsets = (
('Hero секция', {
'fields': ('hero_badge', 'hero_title', 'hero_description')
}),
('Статистика', {
'fields': ('stat_projects', 'stat_clients', 'stat_years', 'stat_support')
}),
('Миссия', {
'fields': (
'mission_badge', 'mission_title', 'mission_description',
'mission_point_1_title', 'mission_point_1_text',
'mission_point_2_title', 'mission_point_2_text',
'mission_point_3_title', 'mission_point_3_text',
)
}),
('Видение', {
'fields': ('vision_badge', 'vision_title', 'vision_description')
}),
('Навыки', {
'fields': (
'skill_1_name', 'skill_1_percent',
'skill_2_name', 'skill_2_percent',
'skill_3_name', 'skill_3_percent',
'skill_4_name', 'skill_4_percent',
)
}),
('Команда', {
'fields': ('team_badge', 'team_title', 'team_description')
}),
('Ценности', {
'fields': (
'values_badge', 'values_title',
'value_1_icon', 'value_1_title', 'value_1_text',
'value_2_icon', 'value_2_title', 'value_2_text',
'value_3_icon', 'value_3_title', 'value_3_text',
'value_4_icon', 'value_4_title', 'value_4_text',
)
}),
('Контакты', {
'fields': ('contact_title', 'contact_description')
}),
('Настройки', {
'fields': ('is_active',)
}),
)
def has_add_permission(self, request):
# Разрешить создание если нет ни одной записи
return AboutPage.objects.count() == 0
def has_delete_permission(self, request, obj=None):
# Запретить удаление
return False
@admin.register(FooterSettings)
class FooterSettingsAdmin(admin.ModelAdmin):
list_display = ('company_name', 'email', 'is_active', 'updated_at')
list_filter = ('is_active', 'updated_at')
search_fields = ('company_name', 'email')
fieldsets = (
('Информация о компании', {
'fields': ('company_name', 'company_description', 'company_logo_icon')
}),
('Социальные сети', {
'fields': ('telegram_url', 'instagram_url', 'linkedin_url', 'github_url', 'facebook_url', 'twitter_url'),
'classes': ('collapse',)
}),
('Контактная информация', {
'fields': ('email', 'phone', 'address')
}),
('Меню футера', {
'fields': (
'show_services_menu', 'services_title',
'show_company_menu', 'company_menu_title'
),
'classes': ('collapse',)
}),
('Copyright', {
'fields': ('copyright_text',)
}),
('Интеграция скриптов', {
'fields': ('google_analytics', 'google_adsense', 'yandex_metrika', 'facebook_pixel'),
'description': 'Вставьте коды аналитики без тегов <script></script>',
'classes': ('collapse',)
}),
('Дополнительные скрипты', {
'fields': ('custom_head_scripts', 'custom_body_scripts'),
'description': 'Вставьте дополнительные скрипты С тегами <script></script>',
'classes': ('collapse',)
}),
('Настройки', {
'fields': ('is_active',)
}),
)
def has_add_permission(self, request):
# Разрешить создание если нет ни одной записи
return FooterSettings.objects.count() == 0
def has_delete_permission(self, request, obj=None):
# Запретить удаление единственной активной записи
return False
@admin.register(TeamMember)
class TeamMemberAdmin(admin.ModelAdmin):
list_display = ('full_name', 'position', 'order', 'is_active', 'email', 'updated_at')
list_filter = ('is_active', 'position')
search_fields = ('first_name', 'last_name', 'position', 'email')
list_editable = ('order', 'is_active')
fieldsets = (
('Основная информация', {
'fields': ('first_name', 'last_name', 'position', 'photo')
}),
('О специалисте', {
'fields': ('bio', 'specialization')
}),
('Контакты', {
'fields': ('email', 'phone', 'telegram', 'linkedin', 'github'),
'classes': ('collapse',)
}),
('Настройки отображения', {
'fields': ('order', 'is_active')
}),
)
def full_name(self, obj):
return obj.full_name
full_name.short_description = 'ФИО' # type: ignore
full_name.admin_order_field = 'last_name' # type: ignore
@admin.register(SiteSettings)
class SiteSettingsAdmin(admin.ModelAdmin):
list_display = ('currency_symbol',)
fieldsets = (
('Настройки валюты', {
'fields': ('currency_symbol',)
}),
)
def has_add_permission(self, request):
# Запретить создание новых записей (singleton)
return not SiteSettings.objects.exists()
def has_delete_permission(self, request, obj=None):
# Запретить удаление настроек
return False
@admin.register(ContactSettings)
class ContactSettingsAdmin(admin.ModelAdmin):
list_display = ('company_name', 'email', 'phone', 'telegram', 'updated_at')
fieldsets = (
('📋 Основная информация', {
'fields': ('company_name',),
'description': 'Название компании'
}),
('📞 Основные контакты', {
'fields': ('email', 'phone', 'telegram', 'whatsapp'),
'description': 'Главные каналы связи с клиентами'
}),
('📍 Адрес и режим работы', {
'fields': ('address', 'working_hours'),
}),
('🌐 Социальные сети', {
'fields': (
'telegram_url',
'instagram_url',
'linkedin_url',
'facebook_url',
'twitter_url',
'youtube_url',
'github_url'
),
'classes': ('collapse',),
'description': 'Ссылки на страницы в социальных сетях'
}),
('📧 Дополнительные контакты', {
'fields': ('support_email', 'sales_email', 'emergency_phone'),
'classes': ('collapse',),
'description': 'Специализированные контакты (опционально)'
}),
)
def has_add_permission(self, request):
# Запретить создание новых записей (singleton)
return not ContactSettings.objects.exists()
def has_delete_permission(self, request, obj=None):
# Запретить удаление контактов
return False
class Media:
css = {
'all': ('admin/css/forms.css',)
}