153 lines
5.7 KiB
Python
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 "-"
|