简体   繁体   English

如何自定义/过滤 django 管理面板 forms 数据?

[英]How to customize/filter django admin panel forms data?

I created models as below;我创建了如下模型; Team model stores different team names, Tournament model is used to create a tournament and add teams into it and finally Game model where I select a tournament, add two teams and create a game. Team model stores different team names, Tournament model is used to create a tournament and add teams into it and finally Game model where I select a tournament, add two teams and create a game. My problem is in Admin panel, while creating a game after selecting a tournament I have to select two teams from the choice list, instead of getting just the teams participating in the Tournament, I am getting all the available teams from the Team model.我的问题出在管理面板中,在选择锦标赛后创建游戏时,我必须从选择列表中选择两支球队 select,而不是只获得参加比赛的球队,而是从球队 model 获得所有可用的球队。

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

My Admin panel customization:我的管理面板自定义:

class TeamInline(admin.TabularInline):
    model = Game.teams.through

class Game(admin.ModelAdmin):
    fields = ['name']
    inlines = [TeamInline]

在此处输入图像描述

Django Admin Inline use ModelForm to render it's content(described in doc ) so you need to override the child form . Django Admin Inline 使用 ModelForm 呈现其内容(在doc中描述),因此您需要覆盖子form

After that set custom formset to pass parent to child form, and in the child form override initial value with init within form doc之后设置自定义formset集以将父表单传递给子表单,并在子表单中用表单文档中的init覆盖初始值

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
  • this custom filtered queryset only work with edit form of the game(doesn't work on create game, it will show all teams)此自定义过滤查询集仅适用于游戏的编辑形式(不适用于创建游戏,它将显示所有团队)
  • parent_object refer to the Game instance when you editing parent_object是指编辑时的游戏实例

the way to get parent instance in Inline Admin Form come from this answer在内联管理表单中获取父实例的方法来自这个答案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM