Чтобы настроить отображение связанного поля (ForeignKey) в админ-панели Django с использованием Inline, необходимо создать класс Inline, наследующий `admin.TabularInline` или `admin.StackedInline`, и затем связать его с соответствующей моделью в админ-классе родительской модели.
Ниже приведен пример настройки Inline для модели `ScreenButton`, предполагая, что у вас есть также модели `Screen` и `Practicum`, причем `Screen` связан с `Practicum` через ForeignKey.
```python
from django.contrib import admin
from .models import Practicum, Screen, ScreenButton
class ScreenButtonInline(admin.TabularInline): # или admin.StackedInline
model = ScreenButton
# Здесь можно добавить дополнительные настройки,
# например 'extra' для числа отображаемых пустых форм
class ScreenAdmin(admin.ModelAdmin):
inlines = [ScreenButtonInline,]
# Другие настройки админ-класса на ваше усмотрение
admin.site.register(Screen, ScreenAdmin)
```
Теперь, чтобы ограничить выбор экранов в поле `screen` только теми, которые относятся к тому же объекту `Practicum`, что и текущий экран, можно использовать прием с фильтрацией полей формы в админке. Это можно сделать с помощью переопределения метода `formfield_for_foreignkey` в админ-классе Inline следующим образом:
```python
from django import forms
class ScreenButtonInline(admin.TabularInline):
model = ScreenButton
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "screen":
if request._obj_ is not None:
kwargs["queryset"] = Screen.objects.filter(practicum=request._obj_.practicum)
return super().formfield_for_foreignkey(db_field, request, **kwargs)
class ScreenAdmin(admin.ModelAdmin):
inlines = [ScreenButtonInline,]
def get_form(self, request, obj=None, **kwargs):
# Сохраняем ссылку на текущий экран для использования в Inline
request._obj_ = obj
return super(ScreenAdmin, self).get_form(request, obj, **kwargs)
admin.site.register(Screen, ScreenAdmin)
```
В этом подходе, когда вы открываете экран (объект `Screen`) в админ-панели, объект экрана передается в `get_form`, откуда он становится доступным через `request._obj_`. Затем метод `formfield_for_foreignkey` проверяет имя поля и в случае, если это поле `screen`, фильтрует QuerySet для этого поля так, чтобы в нём остались только записи, которые относятся к той же практике (объекту `Practicum`), что и редактируемый экран.
Учтите, что использование атрибута `_obj_` - это просто соглашение; вы можете использовать любое другое имя атрибута. Перед использованием этого кода, убедитесь, что у вас корректно установлены отношения ForeignKey в вашей модели и что названия полей и моделей соответствуют вашему случаю использования.