Подтвердить что ты не робот

Внешние ключи в диалоговом окне администратора django

Если модель django содержит поле внешнего ключа, и если это поле отображается в режиме списка, то оно отображается как текст, а не отображается ссылка на посторонний объект.

Можно ли автоматически отображать все внешние ключи как ссылки вместо плоского текста?

(конечно, это можно сделать на поле по полю, но существует ли общий метод?)

Пример:

class Author(models.Model):
    ...

class Post(models.Model):
    author = models.ForeignKey(Author)

Теперь я выбираю ModelAdmin так, что автор появляется в режиме списка:

class PostAdmin(admin.ModelAdmin):
    list_display = [..., 'author',...]

Теперь в режиме списка поле автора будет использовать метод __unicode__ класса Author для отображения автора. В верхней части этого я хотел бы ссылку, указывающую на URL соответствующего автора в админ-сайте. Возможно ли это?

Ручной метод:

Для полноты я добавлю ручной метод. Было бы добавить метод author_link в класс PostAdmin:

def author_link(self, item):
    return '<a href="../some/path/%d">%s</a>' % (item.id, unicode(item))
author_link.allow_tags = True

Это будет работать для этой конкретной области, но это не, что я хочу. Я хочу, чтобы общий метод достигал такого же эффекта. (Одна из проблем заключается в том, как автоматически определить путь к объекту на сайте администратора django.)

4b9b3361

Ответ 1

Я не думаю, что есть механизм, чтобы делать то, что вы хотите автоматически из коробки.

Но если вы определяете путь к странице редактирования admin на основе идентификатора объекта, все, что вам нужно, это две части информации:

a) self.model._meta.app_label

b) self.model._meta.module_name

Затем, например, перейти на страницу редактирования для этой модели:

'../%s_%s_change/%d' % (self.model._meta.app_label, self.model._meta.module_name, item.id)

Взгляните на django.contrib.admin.options.ModelAdmin.get_urls, чтобы увидеть, как они это делают.

Я предполагаю, что у вас может быть вызываемый, который принимает имя модели и идентификатор, создает модель указанного типа, чтобы получить метку и имя (нет необходимости ударять по базе данных) и генерирует вышеприведенный URL.

Но вы уверены, что не можете воспользоваться встроенными линиями? Это сделало бы для лучшего пользовательского интерфейса иметь все связанные компоненты на одной странице...

Изменить:

Inlines (связанный с документами) позволяет интерфейсу администратора отображать отношения родитель-потомок на одной странице, а не разбивать на две.

В примере Post/Author, который вы указали, использование встроенных строк означает, что страница редактирования сообщений также отображает встроенную форму для добавления/редактирования/удаления авторов. Гораздо более естественным для конечного пользователя.

Что вы можете сделать в своем представлении списка администратора, создайте вызываемую в модели Post модель, которая будет отображать список авторов, разделенных запятыми. Таким образом, у вас будет просмотр списка сообщений, показывающий правильных авторов, и вы отредактируете авторов, связанных с сообщением, непосредственно в интерфейсе Post admin.

Ответ 2

Я искал решение той же проблемы и столкнулся с этим вопросом... в конечном итоге решил это сам. 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')

Заменить 'partial' на Django 'curry', если не использовать python >= 2.5.