demo-int-table/back/object/admin.py

153 lines
5.7 KiB
Python

from django.contrib import admin
from django.db import models
from import_export.admin import ImportExportModelAdmin
from .models import ClickableArea, Element3D, Environment, Scene3D
# Админ-класс для Scene3D
@admin.register(Scene3D)
class Scene3DAdmin(admin.ModelAdmin):
list_display = ('name', 'description', 'element_count')
search_fields = ('name', 'description')
autocomplete_fields = ('elements',) # Используем автодополнение
# Метод для подсчета количества связанных элементов
@admin.display(description='Количество элементов')
def element_count(self, obj):
return obj.elements.count()
@admin.register(Environment)
class EnvironmentAdmin(admin.ModelAdmin):
list_display = ("id", "clear_color_display", "clear_color_to_display", "file_count")
list_filter = ("clear_color", "clear_color_to")
search_fields = ("id",)
readonly_fields = ("file_preview",)
# Метод для отображения цвета clear_color
@admin.display(description="Цвет очистки (начальный)", empty_value="-")
def clear_color_display(self, obj):
if obj.clear_color:
return f'<div style="background-color:{obj.clear_color}; width:50px; height:15px;"></div>'
return "-"
clear_color_display.allow_tags = True
# Метод для отображения цвета clear_color_to
@admin.display(description="Цвет очистки (конечный)", empty_value="-")
def clear_color_to_display(self, obj):
if obj.clear_color_to:
return f'<div style="background-color:{obj.clear_color_to}; width:50px; height:15px;"></div>'
return "-"
clear_color_to_display.allow_tags = True
# Метод для подсчета количества загруженных файлов
@admin.display(description="Количество файлов", empty_value="0")
def file_count(self, obj):
return sum(
bool(getattr(obj, field.name))
for field in obj._meta.fields
if isinstance(field, models.FileField)
)
# Метод для предпросмотра файлов
@admin.display(description="Предпросмотр файлов")
def file_preview(self, obj):
preview_html = []
if obj.hdr_gainmap:
preview_html.append(
f'<a href="{obj.hdr_gainmap.url}" target="_blank">Просмотр Gainmap</a>'
)
if obj.hdr_json:
preview_html.append(
f'<a href="{obj.hdr_json.url}" target="_blank">Просмотр JSON</a>'
)
if obj.hdr_webp:
preview_html.append(
f'<a href="{obj.hdr_webp.url}" target="_blank">Просмотр WEBP</a>'
)
return "<br>".join(preview_html) or "-"
file_preview.allow_tags = True
@admin.register(Element3D)
class Element3DAdmin(admin.ModelAdmin):
list_display = (
"name",
"model_file_display",
"is_enabled",
"can_not_disable",
"position_display",
"scenes_count",
)
list_filter = ("is_enabled", "can_not_disable")
search_fields = ("name", "description")
readonly_fields = ("model_file_preview",)
# Метод для отображения пути к файлу модели
@admin.display(description="Файл модели", empty_value="-")
def model_file_display(self, obj):
return obj.model_file.name if obj.model_file else "-"
# Метод для отображения позиции элемента
@admin.display(description="Позиция (X, Y, Z)")
def position_display(self, obj):
return f"({obj.x_pos}, {obj.y_pos}, {obj.z_pos})"
# Метод для подсчета количества связанных сцен
@admin.display(description="Количество сцен", empty_value="0")
def scenes_count(self, obj):
return obj.scene3d_set.count()
# Метод для предпросмотра файла модели
@admin.display(description="Предпросмотр файла")
def model_file_preview(self, obj):
if obj.model_file:
return f'<a href="{obj.model_file.url}" target="_blank">Просмотр файла</a>'
return "-"
model_file_preview.allow_tags = True
# Декоратор для регистрации модели ClickableArea
@admin.register(ClickableArea)
class ClickableAreaAdmin(admin.ModelAdmin):
list_display = (
"name",
"description_shortened",
"source_element",
"target_scene",
"object_name",
)
list_filter = ("source__name", "target__name")
search_fields = (
"name",
"description",
"object_name",
"source__name",
"target__name",
)
autocomplete_fields = ("source", "target")
# Метод для отображения укороченного описания
@admin.display(description="Описание", empty_value="-")
def description_shortened(self, obj):
return (
(obj.description[:50] + "...")
if len(obj.description) > 50
else obj.description
)
# Метод для отображения связанного элемента (source)
@admin.display(description="Элемент 3D", empty_value="-")
def source_element(self, obj):
return obj.source.name if obj.source else "-"
# Метод для отображения связанной сцены (target)
@admin.display(description="Сцена", empty_value="-")
def target_scene(self, obj):
return obj.target.name if obj.target else "-"