web-dev-qa-db-ja.com

Django adminのリスト表示リンクを変更する

Django管理者リストの表示でオブジェクトのリンクを変更しようとしています。これまでのところ、次のようになっています。

class FooModelAdmin(admin.ModelAdmin):
    fields = ('foo','bar')
    list_display = ('foo_link','bar')

    def foo_link(self,obj):
        return u'<a href="/foos/%s/">%s</a>' % (obj.foo,obj)
    domain_link.allow_tags = True
    domain_link.short_description = "foo"

これにより、元のリスト表示リンク内に別のリンクが生成されます。

<a href="/admin/app/model/pk/"><a href="/foos/foo/">Foo</a></a>
23
tomfmason

解決策は、initをオーバーライドし、list_display_linksをNoneに設定することでした。

class FooModelAdmin(admin.ModelAdmin):
    fields = ('foo','bar')
    list_display = ('foo_link','bar')

    def foo_link(self,obj):
        return u'<a href="/foos/%s/">%s</a>' % (obj.foo,obj)
    foo_link.allow_tags = True
    foo_link.short_description = "foo"
    def __init__(self,*args,**kwargs):
        super(FooModelAdmin, self).__init__(*args, **kwargs)
        self.list_display_links = (None, )
29
tomfmason

それを行う正しい方法は、ChangeListをサブクラス化し、url_for_resultメソッドをオーバーライドして、必要な正しい変更URLを作成することだと思います。

Admin.ModelAdminサブクラスのget_changelistをオーバーライドして、新しいクラスを返します。

from Django.contrib.admin.views.main import ChangeList
from Django.contrib.admin.util import quote

class FooChangeList(ChangeList):
    def url_for_result(self, result):
        pk = getattr(result, self.pk_attname)
        return '/foos/foo/%d/' % (quote(pk))

class FooAdmin(admin.ModelAdmin):
    def get_changelist(self, request, **kwargs):
        return FooChangeList
27
Fred

デフォルトでは、リスト表示の最初の列は管理者編集ページにリンクされます。別の列をそのリンクにしたい場合、非常に簡単な方法は次のとおりです。

class FooModelAdmin(admin.ModelAdmin):
    list_display = ('foo_link', 'bar', 'another_bar', )
    list_display_links = ('foo_link', 'another_bar', )

foo_linkがモデルのプロパティでない場合は、次のように呼び出すことができます。

class FooModelAdmin(admin.ModelAdmin):
    list_display = ('foo_link', 'bar', 'another_bar', )
    list_display_links = ('foo_link', 'another_bar', )

    def foo_link(self, obj):
        return "%s blah blah" % obj.some_property # or anything you prefer e.g. an edit button

私のプロジェクトからの完全な例:

class SchoolTeacherAdmin(admin.ModelAdmin):
    list_display = ('name', 'designation', 'school_name', 'school_code', 'date_of_birth', 'mobile', 'nid', 'edit', )
    list_display_links = ('edit', )

    def school_code(self, obj):
        return obj.school.code

    def school_name(self, obj):
        return obj.school.name.upper()

    def edit(self, obj):
        return "Edit"
7
Nayan

このアイデアを自分でフォローした後(リスト表示から実際のページにリンクするため)、私は考え直しました。考慮しなければならない2つのページがあります。モデルの管理ページとモデルの実際の公開ページ(おそらく詳細ビュー)です。管理者から公開ページにリンクすると(CMSページであっても)、管理者ページへの接続が失われます。

モデルの管理ページは、実際には「プレビュー」リンク(通常は右上に配置されています)を介して公開ページにリンクしています。このリンクはmodel_object.get_absolute_url()から派生しています。

したがって、プレビューリンクが指す場所を変更する場合は、get_absolute_url()をオーバーライドするだけです。そしてこの場合、とにかくそれを行うのはおそらく良いことです。なぜなら、他のすべての場所でもそのURLを利用したいと思うからです。

1
Risadinha

リンクはそこでラップされているため、テンプレートをオーバーライドする必要があります。 Edit Django User admin template をご覧ください。

0
Andrew Sledge