django管理列表中的外键显示

django管理列表中的外键显示,django,django-admin,foreign-keys,Django,Django Admin,Foreign Keys,如果django模型包含外键字段,并且该字段以列表模式显示,则它将显示为文本,而不是显示指向外部对象的链接 是否可以将所有外键自动显示为链接而不是纯文本 (当然可以逐个现场进行,但是否有通用方法?) 示例: class Author(models.Model): ... class Post(models.Model): author = models.ForeignKey(Author) 现在,我选择一个ModelAdmin,以便作者以列表模式显示: class PostA

如果django模型包含外键字段,并且该字段以列表模式显示,则它将显示为文本,而不是显示指向外部对象的链接

是否可以将所有外键自动显示为链接而不是纯文本

(当然可以逐个现场进行,但是否有通用方法?)

示例

class Author(models.Model):
    ...

class Post(models.Model):
    author = models.ForeignKey(Author)
现在,我选择一个ModelAdmin,以便作者以列表模式显示:

class PostAdmin(admin.ModelAdmin):
    list_display = [..., 'author',...]
现在在列表模式下,author字段将只使用
author
类的
\uuuuunicode\uuuu
方法来显示作者。最重要的是,我想一个链接指向相应的作者在管理网站的url。可能吗

手动方法

class Author(models.Model):
    ...

class Post(models.Model):
    author = models.ForeignKey(Author)
为了完整性,我添加了手动方法。在
PostAdmin
类中添加方法
author\u link

def author_link(self, item):
    return '<a href="../some/path/%d">%s</a>' % (item.id, unicode(item))
author_link.allow_tags = True
def author_链接(自身,项目):
返回“”%(item.id,unicode(item))
author\u link.allow\u tags=True

这将适用于特定领域,但这不是我想要的。我想要一个通用的方法来达到同样的效果。(其中一个问题是如何在django管理站点中自动找到对象的路径。)

我认为没有一种机制可以自动完成您想要的操作

但就根据对象id确定管理员编辑页面的路径而言,您只需要两条信息:

a)
self.model.\u meta.app\u标签

b)
self.model.\u元模块\u名称

然后,例如,要转到该模型的编辑页面,您可以执行以下操作:

'../%s_%s_change/%d' % (self.model._meta.app_label, self.model._meta.module_name, item.id)
查看
django.contrib.admin.options.ModelAdmin.get_url
以了解它们是如何做到的

我想您可以有一个callable,它接受一个模型名和一个id,创建一个指定类型的模型,只获取标签和名称(无需访问数据库),并生成上面的URL

但是你确定你不能使用内联线吗?将所有相关组件放在一个页面中将有助于实现更好的用户界面

编辑:

(链接到文档)允许管理员界面在一个页面中显示父子关系,而不是将其拆分为两个页面

在您提供的Post/Author示例中,使用内联线意味着用于编辑Post的页面还将显示用于添加/编辑/删除作者的内联表单。对最终用户来说更自然


在管理列表视图中可以做的是在Post模型中创建一个可调用的,该模型将呈现一个以逗号分隔的作者列表。因此,您的帖子列表视图将显示合适的作者,您可以在帖子管理界面中直接编辑与帖子相关联的作者。

我正在寻找解决同一问题的方法,并遇到了这个问题。。。最后我自己解决了。OP可能不再感兴趣了,但这对某些人仍然有用

from functools import partial
from django.forms import MediaDefiningClass

class ModelAdminWithForeignKeyLinksMetaclass(MediaDefiningClass):

    def __getattr__(cls, name):

        def foreign_key_link(instance, field):
            target = getattr(instance, field)
            return u'<a href="../../%s/%s/%d">%s</a>' % (
                target._meta.app_label, target._meta.module_name, target.id, unicode(target))

        if name[:8] == 'link_to_':
            method = partial(foreign_key_link, field=name[8:])
            method.__name__ = name[8:]
            method.allow_tags = True
            setattr(cls, name, method)
            return getattr(cls, name)
        raise AttributeError

class Book(models.Model):
    title = models.CharField()
    author = models.ForeignKey(Author)

class BookAdmin(admin.ModelAdmin):
    __metaclass__ = ModelAdminWithForeignKeyLinksMetaclass

    list_display = ('title', 'link_to_author')
从functools导入部分
从django.forms导入MediaDefiningClass
类ModelAdminWithForeignKeyLinksMetaclass(MediaDefiningClass):
def_u_getattr__(cls,名称):
def外键链接(实例,字段):
target=getattr(实例,字段)
返回u'%(
目标。_meta.app_标签,目标。_meta.module_名称,target.id,unicode(目标))
如果名称[:8]=“链接到”:
方法=部分(外键链接,字段=名称[8:])
方法。\名称\名称=name[8:]
method.allow_tags=True
setattr(cls、名称、方法)
返回getattr(cls,名称)
提高属性错误
教材(models.Model):
title=models.CharField()
作者=模型。外键(作者)
类BookAdmin(admin.ModelAdmin):
__元类\uuux=ModelAdminWithForeignKeyLinksMetaclass
列表显示=('title','link'到作者')
如果不使用python>=2.5,请将“partial”替换为Django的“curry”。

请参见

例如:

from django.utils.html import format_html
def get_admin_change_link(app_label, model_name, obj_id, name):
    url = reverse('admin:%s_%s_change' % (app_label, model_name),
              args=(obj_id,))
    return format_html('<a href="%s">%s</a>' % (
        url, unicode(name)
    ))
来自django.utils.html导入格式\u html
def get_admin_change_链接(应用程序标签、型号名称、obj_id、名称):
url=reverse('管理员:%s\u%s\u更改“%”(应用程序标签、型号名称),
args=(对象id,)
返回格式为html(“”%(
url,unicode(名称)
))

谢谢您的回答!你能详细说明内联线的使用吗?这会有什么帮助?@Olivier:编辑了我的答案,为你指出了关于内联线的正确方向。Itai Tavor,谢谢你的回答,这真的很有说服力,但可能会引起问题,细节在里面。对我来说,使用绝对路径更有效,因为在对象细节页面上的链接是正确的,而不仅仅是在列表页面上。ModelAdminWith的参数是什么。。。方法?我没有一个“MediaDefineClass”作为表单?漂亮的解决方案。必须将“target.\u meta.module\u name”更改为“target.\u meta.model\u name”。效果很好。