"""
Административная панель для чата.
"""
from django.contrib import admin
from django.utils.html import format_html
from django.urls import reverse
from .models import Chat, ChatParticipant, Message, MessageFile, MessageRead, MessageReaction
@admin.register(Chat)
class ChatAdmin(admin.ModelAdmin):
"""Админ интерфейс для чатов."""
list_display = [
'uuid_short',
'name_display',
'type_badge',
'created_by_link',
'participants_count',
'messages_count',
'last_message_at',
'is_archived_badge',
'created_at'
]
list_filter = [
'chat_type',
'is_archived',
'created_at'
]
search_fields = [
'uuid',
'name',
'description'
]
readonly_fields = [
'uuid',
'messages_count',
'last_message_at',
'created_at',
'updated_at'
]
def uuid_short(self, obj):
"""Короткий UUID."""
return str(obj.uuid)[:8]
uuid_short.short_description = 'ID'
def name_display(self, obj):
"""Название чата."""
return obj.name or f"Чат {str(obj.uuid)[:8]}"
name_display.short_description = 'Название'
def type_badge(self, obj):
"""Бейдж типа чата."""
colors = {
'direct': '#007bff',
'group': '#28a745'
}
return format_html(
'{}',
colors.get(obj.chat_type, '#000'),
obj.get_chat_type_display()
)
type_badge.short_description = 'Тип'
def created_by_link(self, obj):
"""Ссылка на создателя."""
if obj.created_by:
url = reverse('admin:users_user_change', args=[obj.created_by.id])
return format_html('{}', url, obj.created_by.get_full_name())
return '-'
created_by_link.short_description = 'Создатель'
def participants_count(self, obj):
"""Количество участников."""
return obj.participants.count()
participants_count.short_description = 'Участников'
def is_archived_badge(self, obj):
"""Бейдж архивации."""
if obj.is_archived:
return format_html('✗ Архивирован')
return format_html('✓ Активен')
is_archived_badge.short_description = 'Статус'
@admin.register(ChatParticipant)
class ChatParticipantAdmin(admin.ModelAdmin):
"""Админ интерфейс для участников чата."""
list_display = [
'user_link',
'chat_link',
'role_badge',
'unread_count',
'is_muted',
'is_pinned',
'joined_at'
]
list_filter = [
'role',
'is_muted',
'is_pinned',
'joined_at'
]
search_fields = [
'user__email',
'chat__name'
]
def user_link(self, obj):
"""Ссылка на пользователя."""
url = reverse('admin:users_user_change', args=[obj.user.id])
return format_html('{}', url, obj.user.get_full_name())
user_link.short_description = 'Пользователь'
def chat_link(self, obj):
"""Ссылка на чат."""
url = reverse('admin:chat_chat_change', args=[obj.chat.id])
name = obj.chat.name or f"Чат {str(obj.chat.uuid)[:8]}"
return format_html('{}', url, name)
chat_link.short_description = 'Чат'
def role_badge(self, obj):
"""Бейдж роли."""
colors = {
'admin': '#dc3545',
'member': '#6c757d'
}
return format_html(
'{}',
colors.get(obj.role, '#000'),
obj.get_role_display()
)
role_badge.short_description = 'Роль'
@admin.register(Message)
class MessageAdmin(admin.ModelAdmin):
"""Админ интерфейс для сообщений."""
list_display = [
'uuid_short',
'sender_link',
'chat_link',
'content_preview',
'type_badge',
'is_edited',
'is_deleted',
'created_at'
]
list_filter = [
'message_type',
'is_edited',
'is_deleted',
'created_at'
]
search_fields = [
'uuid',
'content',
'sender__email'
]
readonly_fields = [
'uuid',
'is_edited',
'edited_at',
'is_deleted',
'deleted_at',
'created_at'
]
def uuid_short(self, obj):
"""Короткий UUID."""
return str(obj.uuid)[:8]
uuid_short.short_description = 'ID'
def sender_link(self, obj):
"""Ссылка на отправителя."""
if obj.sender:
url = reverse('admin:users_user_change', args=[obj.sender.id])
return format_html('{}', url, obj.sender.get_full_name())
return 'System'
sender_link.short_description = 'Отправитель'
def chat_link(self, obj):
"""Ссылка на чат."""
url = reverse('admin:chat_chat_change', args=[obj.chat.id])
name = obj.chat.name or f"Чат {str(obj.chat.uuid)[:8]}"
return format_html('{}', url, name)
chat_link.short_description = 'Чат'
def content_preview(self, obj):
"""Превью контента."""
return obj.content[:100] if len(obj.content) > 100 else obj.content
content_preview.short_description = 'Содержимое'
def type_badge(self, obj):
"""Бейдж типа."""
colors = {
'text': '#007bff',
'file': '#28a745',
'image': '#17a2b8',
'video': '#dc3545',
'audio': '#ffc107',
'system': '#6c757d'
}
return format_html(
'{}',
colors.get(obj.message_type, '#000'),
obj.get_message_type_display()
)
type_badge.short_description = 'Тип'
@admin.register(MessageFile)
class MessageFileAdmin(admin.ModelAdmin):
"""Админ интерфейс для файлов сообщений."""
list_display = [
'file_name',
'message_link',
'file_size_display',
'file_type',
'created_at'
]
search_fields = ['file_name', 'file_type']
def message_link(self, obj):
"""Ссылка на сообщение."""
url = reverse('admin:chat_message_change', args=[obj.message.id])
return format_html('{}', url, str(obj.message.uuid)[:8])
message_link.short_description = 'Сообщение'
def file_size_display(self, obj):
"""Отображение размера."""
size_mb = obj.file_size / (1024 * 1024)
if size_mb > 1:
return f"{size_mb:.2f} МБ"
size_kb = obj.file_size / 1024
return f"{size_kb:.2f} КБ"
file_size_display.short_description = 'Размер'
@admin.register(MessageRead)
class MessageReadAdmin(admin.ModelAdmin):
"""Админ интерфейс для прочтений."""
list_display = [
'user_link',
'message_link',
'read_at'
]
search_fields = ['user__email']
def user_link(self, obj):
"""Ссылка на пользователя."""
url = reverse('admin:users_user_change', args=[obj.user.id])
return format_html('{}', url, obj.user.get_full_name())
user_link.short_description = 'Пользователь'
def message_link(self, obj):
"""Ссылка на сообщение."""
url = reverse('admin:chat_message_change', args=[obj.message.id])
return format_html('{}', url, str(obj.message.uuid)[:8])
message_link.short_description = 'Сообщение'
@admin.register(MessageReaction)
class MessageReactionAdmin(admin.ModelAdmin):
"""Админ интерфейс для реакций."""
list_display = [
'user_link',
'message_link',
'emoji',
'created_at'
]
search_fields = ['user__email', 'emoji']
def user_link(self, obj):
"""Ссылка на пользователя."""
url = reverse('admin:users_user_change', args=[obj.user.id])
return format_html('{}', url, obj.user.get_full_name())
user_link.short_description = 'Пользователь'
def message_link(self, obj):
"""Ссылка на сообщение."""
url = reverse('admin:chat_message_change', args=[obj.message.id])
return format_html('{}', url, str(obj.message.uuid)[:8])
message_link.short_description = 'Сообщение'