Как настроить/фильтровать данные форм админпанели 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]

enter image description here

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 исходит из этого ответ

Вернуться на верх