change list display link in django admin

我与影子孤独终老i 提交于 2019-12-31 09:16:50

问题


I am trying to change the link for an object in the django admin list display. Here is what I have so far:

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"

This produces another link within the original list display link e.g.

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

回答1:


The solution was to override the init and set the list_display_links to None e.g.

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, )



回答2:


I believe the correct way of doing it, is subclassing ChangeList and override the url_for_result method to create the correct change url you want.

Override the get_changelist in the admin.ModelAdmin subclass to return the new class:

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



回答3:


By default the first column of list display will be link to the admin edit page. If you want another column or columns to be that link, a very easy way is as follows:

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

If foo_link is not a property of the model, it should be a callable like the following:

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

A full example from my project:

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"



回答4:


After following this idea myself (to link from the list display to the actual page) I had second thoughts. There are two pages that you have to consider: the admin page of the model and the actual public page (probably detail view) of the model. If you link from the admin to the public page (even if it is a CMS page) you loose the connection to its admin page.

The admin page of the model actually links to the public page via the "Preview" link (regularly placed at the top right). This link derives from model_object.get_absolute_url().

So, if you want to change where the preview link points you simply have to override get_absolute_url(). And in this case, it's probably a good thing you do that, anyway, because you will likely want to make use of that url in all other places, as well.




回答5:


You need to override the template since the link is wrapped there. Have a look at Edit Django User admin template.



来源:https://stackoverflow.com/questions/3998786/change-list-display-link-in-django-admin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!