Files
smartsoltech_site/smartsoltech/web/admin.py
Andrey K. Choi ec01a2ae10 👥 Добавлено управление персоналом и карьерой
 Новые функции:
- 🧑‍💻 Team модель для управления сотрудниками
  • Полная информация о персонале (имя, должность, отдел)
  • Фотографии и контактные данные
  • Социальные сети (LinkedIn, GitHub, Telegram)
  • Навыки и опыт работы
  • Гибкие настройки отображения

- 💼 Career модель для вакансий
  • Детальное описание позиций
  • Требования и обязанности
  • Зарплатные вилки
  • Типы занятости и уровни опыта
  • Статусы вакансий и дедлайны

🔧 Админ-панель:
- Удобные интерфейсы для HR-менеджмента
- Группировка полей и фильтрация
- Быстрые действия для массовых операций
- Сортировка по приоритету

📊 База данных:
- Миграция 0013_career_team.py
- Оптимизированные индексы и связи
2025-11-25 15:44:57 +09:00

182 lines
7.6 KiB
Python

from django.contrib import admin
from .models import Service, Project, Client, Order, Review, BlogPost, Category, ServiceRequest, HeroBanner, ContactInfo, Team, Career
from .forms import ProjectForm
@admin.register(ContactInfo)
class ContactInfoAdmin(admin.ModelAdmin):
list_display = ('company_name', 'email', 'phone', 'is_active')
list_filter = ('is_active',)
search_fields = ('company_name', 'email', 'phone')
fields = ('company_name', 'email', 'phone', 'telegram', 'address', 'working_hours',
'description', 'call_to_action', 'subtitle', 'is_active')
@admin.register(HeroBanner)
class HeroBannerAdmin(admin.ModelAdmin):
list_display = ('title', 'is_active', 'order', 'created_at')
list_filter = ('is_active', 'created_at')
search_fields = ('title', 'subtitle')
fields = ('title', 'subtitle', 'description', 'image', 'video', 'video_poster',
'button_text', 'button_link', 'is_active', 'order')
list_editable = ('is_active', 'order')
@admin.register(Service)
class ServiceAdmin(admin.ModelAdmin):
list_display = ('name', 'category', 'price', 'has_video')
search_fields = ('name', 'category')
fields = ('name', 'description', 'price', 'category', 'image', 'video', 'video_poster')
def has_video(self, obj):
return bool(obj.video)
has_video.boolean = True
has_video.short_description = 'Есть видео'
@admin.register(Project)
class ProjectAdmin(admin.ModelAdmin):
form = ProjectForm
list_display = ('name', 'client','service', 'status', 'order', 'has_video')
list_filter = ('name', 'client','service', 'status', 'order')
search_fields = ('name', 'client','service', 'status', 'order', 'client__first_name', 'client__last_name')
fields = ('name', 'description', 'completion_date', 'client', 'service', 'order',
'category', 'image', 'video', 'video_poster', 'status')
def has_video(self, obj):
return bool(obj.video)
has_video.boolean = True
has_video.short_description = 'Есть видео'
@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', 'has_video')
list_filter = ('rating',)
search_fields = ('client__first_name', 'service__name')
fields = ('client', 'service', 'project', 'rating', 'comment', 'image', 'video', 'video_poster')
def has_video(self, obj):
return bool(obj.video)
has_video.boolean = True
has_video.short_description = 'Есть видео'
@admin.register(BlogPost)
class BlogPostAdmin(admin.ModelAdmin):
list_display = ('title', 'published_date', 'has_video')
search_fields = ('title',)
fields = ('title', 'content', 'image', 'video', 'video_poster')
def has_video(self, obj):
return bool(obj.video)
has_video.boolean = True
has_video.short_description = 'Есть видео'
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = ('name','description')
search_fields = ('name',)
@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(Team)
class TeamAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name', 'position', 'department', 'is_active', 'display_order')
list_filter = ('department', 'is_active', 'show_on_about')
search_fields = ('first_name', 'last_name', 'position', 'skills')
list_editable = ('display_order', 'is_active')
fieldsets = (
('Основная информация', {
'fields': ('first_name', 'last_name', 'position', 'department')
}),
('Контактные данные', {
'fields': ('email', 'phone', 'photo'),
'classes': ('collapse',)
}),
('Профессиональная информация', {
'fields': ('bio', 'skills', 'experience_years')
}),
('Социальные сети', {
'fields': ('linkedin', 'github', 'telegram'),
'classes': ('collapse',)
}),
('Настройки отображения', {
'fields': ('is_active', 'show_on_about', 'display_order')
}),
)
def get_queryset(self, request):
return super().get_queryset(request).order_by('display_order', 'last_name')
@admin.register(Career)
class CareerAdmin(admin.ModelAdmin):
list_display = ('title', 'department', 'experience_level', 'employment_type', 'status', 'is_featured', 'created_at')
list_filter = ('status', 'employment_type', 'experience_level', 'department', 'is_featured')
search_fields = ('title', 'department', 'description', 'required_skills')
list_editable = ('status', 'is_featured')
fieldsets = (
('Основная информация', {
'fields': ('title', 'department', 'location', 'employment_type', 'experience_level')
}),
('Описание вакансии', {
'fields': ('description', 'responsibilities', 'requirements', 'benefits')
}),
('Зарплата', {
'fields': ('salary_min', 'salary_max', 'salary_currency'),
'classes': ('collapse',)
}),
('Навыки', {
'fields': ('required_skills', 'preferred_skills'),
}),
('Контактная информация', {
'fields': ('contact_email', 'contact_person'),
'classes': ('collapse',)
}),
('Статус и метаданные', {
'fields': ('status', 'is_featured', 'application_deadline', 'published_at')
}),
)
readonly_fields = ('created_at', 'updated_at')
def get_queryset(self, request):
return super().get_queryset(request).order_by('-is_featured', '-created_at')
def save_model(self, request, obj, form, change):
if obj.status == 'active' and not obj.published_at:
from django.utils import timezone
obj.published_at = timezone.now()
super().save_model(request, obj, form, change)
actions = ['mark_as_active', 'mark_as_paused', 'mark_as_closed']
def mark_as_active(self, request, queryset):
from django.utils import timezone
updated = queryset.update(status='active')
queryset.filter(published_at__isnull=True).update(published_at=timezone.now())
self.message_user(request, f'{updated} вакансий отмечены как активные.')
mark_as_active.short_description = "Отметить как активные"
def mark_as_paused(self, request, queryset):
updated = queryset.update(status='paused')
self.message_user(request, f'{updated} вакансий приостановлены.')
mark_as_paused.short_description = "Приостановить"
def mark_as_closed(self, request, queryset):
updated = queryset.update(status='closed')
self.message_user(request, f'{updated} вакансий закрыты.')
mark_as_closed.short_description = "Закрыть"