Как настроить/фильтровать данные форм админпанели django?
Я создал следующие модели: модель Team хранит имена различных команд, модель Tournament используется для создания турнира и добавления в него команд и, наконец, модель Game, в которой я выбираю турнир, добавляю две команды и создаю игру. Моя проблема в панели администратора, при создании игры после выбора турнира я должен выбрать две команды, в списке выбора я получаю все доступные команды в базе данных Teams, вместо только команд, участвующих в турнире.
class Team(models.Model):
name = models.CharField(max_length=30) # Ind, Pak, Aus, Sri, Eng
class Tournament(models.Model):
name = models.CharField(max_length=50) # Asia Cup:
teams = models.ManyToManyField(Team) # Ind, Pak, Sri
class Game(models.Model):
name = models.CharField(max_length=50)
tournament = models.ForeignKey(Tournament, on_delete=models.CASCADE) # Asia Cup
teams = models.ManyToManyField(Team) # Expected: Ind, Pak, Sri
Моя настройка панели администратора:
class TeamInline(admin.TabularInline):
model = Game.teams.through
class Game(admin.ModelAdmin):
fields = ['name']
inlines = [TeamInline]
Django Admin Inline использует ModelForm для вывода своего содержимого (описано в doc), поэтому вам нужно переопределить дочерний form
.
После этого установите пользовательский formset
для передачи родительской формы в дочернюю, а в дочерней форме переопределите начальное значение с помощью init внутри формы doc
class TeamInlineCustomFormSet(BaseInlineFormSet):
def get_form_kwargs(self, index):
kwargs = super().get_form_kwargs(index)
kwargs['parent_object'] = self.instance
return kwargs
class TeamInlineCustomForm(forms.ModelForm):
def __init__(self, *args, parent_object, **kwargs):
self.parent_object = parent_object
super (TeamInlineCustomForm, self).__init__(*args, **kwargs)
if parent_object: # check if has game instance
self.fields['team'].queryset = parent_object.tournament.teams.all()
class Meta:
model = Game.teams.through
class TeamInline(admin.TabularInline):
model = Game.teams.through
formset = TeamInlineCustomFormSet
form = TeamInlineCustomForm
- этот пользовательский фильтрованный набор запросов работает только в форме редактирования игры (не работает при создании игры, будет показывать все команды)
parent_object
обратитесь к экземпляру игры при редактировании
способ получения родительского экземпляра в Inline Admin Form исходит из этого ответ