【问题标题】:In the Django Admin Site, how can I access model properties through an Inline?在 Django 管理站点中,如何通过内联访问模型属性?
【发布时间】:2016-01-03 12:58:02
【问题描述】:

models.py:

class Player(models.Model):
    name = models.CharField(max_length=50)
    email = models.EmailField(max_length=50)

class Tournament(models.Model):
    name = models.CharField(max_length=50)

class TournamentPlayer(models.Model):
    tournament = models.ForeignKey(Tournament)
    player = models.ForeignKey(Player)
    paid = models.BooleanField()

    def player_email(self):
        return self.player.email

admin.py:

class TournamentPlayerInline(admin.TabularInline):
    model = TournamentPlayer
    fields = ('player', 'paid', 'player_email')

@admin.register(Tournament)
class TournamentAdmin(admin.ModelAdmin):
    inlines = [TournamentPlayerInline]

我有一个内联问题。当我在管理站点中启动锦标赛时,我可以看到哪些玩家参加了比赛,以及他们是否付费。我还想显示 Player 中包含的额外信息,例如电子邮件地址。

在 TournamentPlayerInline 中,我认为我可能能够摆脱 fields = ('player', 'paid', 'player_email'),但我得到 FieldError: Unknown field(s) (player_email) specified for TournamentPlayer。

我也试过fields = ('player', 'paid', 'player__email'),但我得到FieldError: Unknown field(s) (player__email) specified for TournamentPlayer。

如果我将player_email 从fields 移动到readonly_fields,我将不再收到错误消息,但也不会显示玩家电子邮件。

这就是我所追求的:

如何从 TournamentPlayerInline 访问 Player 属性?

Django 1.8.4

【问题讨论】:

  • 您是否尝试过将player_email 设为@property?您也可以使用双下划线将其设为 fields = ('player', 'paid', 'player__email') 以表示外键关系。
  • 我在def player_email(self):上方添加了@property,没有效果。也试过 player__email 没有效果。
  • 嗯...查看此问题中显示的管理员定义:stackoverflow.com/questions/163823/…
  • 在def player_email之后添加了player_email.admin_order_field = 'player__email',没有效果。
  • 您希望player_email 在管理员中可编辑吗?否则,您只需将其从 fields 中删除并将其添加到 readonly_fields 即可。

标签: python django


【解决方案1】:

Monkey 的回答几乎是正确的。您需要做的唯一更改是您的admin.py,它只是将'player_email' 添加到fields 和readonly_fields。在fields 中更改'player_email' 的位置将允许您按照您的示例对其进行排序。

class TournamentPlayerInline(admin.TabularInline):
    model = TournamentPlayer
    fields = ('player', 'player_email', 'paid',)
    readonly_fields = ('player_email',)

@admin.register(Tournament)
class TournamentAdmin(admin.ModelAdmin):
    inlines = [TournamentPlayerInline]

【讨论】:

    【解决方案2】:

    如果您不要求可以从内联编辑 player_email,那么您可以使用 readonly_fields 变量来完成此操作:

    class TournamentPlayerInline(admin.TabularInline):
        model = TournamentPlayer
        fields = ('player', 'paid')
        readonly_fields = ('player_email',)
    
    @admin.register(Tournament)
    class TournamentAdmin(admin.ModelAdmin):
        inlines = [TournamentPlayerInline]
    

    【讨论】:

    • 虽然这不会产生错误,但在查看锦标赛时也不会显示玩家电子邮件。这就是我所追求的:i.imgur.com/IPIZNId.png
    【解决方案3】:

    作为替代方案,如果您不直接使用它,则不必在模型中定义您的自定义属性,而只想在管理员中查看它——您可以通过 mixin 在 Inline 中创建它:

    models.py

    class Player(models.Model):
        name = models.CharField(max_length=50)
        email = models.EmailField(max_length=50)
    
    class Tournament(models.Model):
        name = models.CharField(max_length=50)
    
    class TournamentPlayer(models.Model):
        tournament = models.ForeignKey(Tournament)
        player = models.ForeignKey(Player)
        paid = models.BooleanField()
    

    admin.py

    class PlayerEmailMixin(object):
        def player_email(self, obj):
            return obj.player.email
    
        player_email.short_description = "Player Email"
    
    class TournamentPlayerInline(PlayerEmailMixin, admin.TabularInline):
        model = TournamentPlayer
        fields = ('player', 'player_email', 'paid', )
        readonly_fields = ('player_email',)
    
    @admin.register(Tournament)
    class TournamentAdmin(admin.ModelAdmin):
        inlines = [TournamentPlayerInline]
    

    您也可以通过这种方式将其设为 mailto URI:

    class PlayerEmailMixin(object):
        def player_email(self, obj):
            return '<a href="mailto:{0}"><strong>{0}</strong></a>'.format(obj.player.email)
    
        player_email.short_description = "Player Email"
        player_email.allow_tags = True
    

    这在 Django 1.9.5 中是已知的

    【讨论】:

      猜你喜欢
      • 2016-02-18
      • 2019-01-31
      • 1970-01-01
      • 1970-01-01
      • 2015-11-15
      • 2016-01-03
      • 1970-01-01
      • 2010-12-29
      • 1970-01-01
      相关资源
      最近更新 更多