Чтобы реализовать двухуровневый инлайн в админке Django с использованием полиморфизма, можно использовать следующий подход, который основан на использовании абстрактных базовых классов и создании конкретных подклассов для каждого типа блока.
Предположим, у нас есть следующая структура моделей:
```python
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
from django.db import models
class Screen(models.Model):
name = models.CharField(max_length=255)
class Block(models.Model):
screen = models.ForeignKey(Screen, related_name='blocks', on_delete=models.CASCADE)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
class Meta:
abstract = True
class TextBlock(Block):
text = models.TextField()
class ImageBlock(Block):
image = models.ImageField(upload_to='images/')
```
В этом случае каждый `Block` может быть либо `TextBlock`, либо `ImageBlock`.
Вам нужно будет создать соответствующие административные классы для каждого вида блока и зарегистрировать их в системе администрирования Django. Также потребуется определить инлайны для связанных объектов:
```python
from django.contrib import admin
from django.contrib.contenttypes.admin import GenericTabularInline
from .models import Screen, TextBlock, ImageBlock
class TextBlockInline(GenericTabularInline):
model = TextBlock
class ImageBlockInline(GenericTabularInline):
model = ImageBlock
class ScreenAdmin(admin.ModelAdmin):
inlines = [TextBlockInline, ImageBlockInline]
admin.site.register(Screen, ScreenAdmin)
```
При таком подходе, инлайны для `TextBlock` и `ImageBlock` будут отображаться в админке как часть `Screen`.
Однако, если вы хотите использовать более гибкий и динамичный подход, к которому можно динамически добавлять новые типы блоков без необходимости изменения админ-класса, потребуется сложная реализация через `GenericForeignKey` и возможно использование сторонних библиотек, таких как `django-polymorphic` для упрощения работы с полиморфными моделями.
При использовании `django-polymorphic`, модели и административная часть могли бы выглядеть следующим образом:
```python
from django.db import models
from polymorphic.models import PolymorphicModel
from polymorphic.admin import PolymorphicParentModelAdmin, PolymorphicChildModelAdmin
class Block(PolymorphicModel):
screen = models.ForeignKey(Screen, related_name='blocks', on_delete=models.CASCADE)
class TextBlock(Block):
text = models.TextField()
class ImageBlock(Block):
image = models.ImageField(upload_to='images/')
class BlockChildAdmin(PolymorphicChildModelAdmin):
base_model = Block
class TextBlockAdmin(BlockChildAdmin):
base_model = TextBlock
class ImageBlockAdmin(BlockChildAdmin):
base_model = ImageBlock
class BlockParentAdmin(PolymorphicParentModelAdmin):
base_model = Block
child_models = (TextBlock, ImageBlock)
admin.site.register(Block, BlockParentAdmin)
admin.site.register(TextBlock, TextBlockAdmin)
admin.site.register(ImageBlock, ImageBlockAdmin)
```
Данный пример использует полиморфные модели `django-polymorphic`, которые позволяют легко определять административную часть для каждого типа блока. Это делает возможным выбор типа блока прямо в админке, сохраняя при этом понятное и чистое отображение в административном интерфейсе.