1

我正在尝试在 Django 管理员的列表显示中显示绝对 URI:

from django.contrib import admin
class MyAdmin(admin.ModelAdmin):
    list_display = (
        'full_uri',
    )

    readonly_fields = (
        'full_uri',
    )

    def full_uri(self, obj):
        return u'<a href="{url}">{url}'.format(
            url = request.build_absolute_uri(reverse('view_name', args=(obj.pk, )))
        )
    full_uri.allow_tags = True

问题 - 我无权访问请求对象(其中build_absolute_uri定义)。

我试图在本地覆盖changelist_view和存储请求,但这不是线程安全的。

我也尝试过这个解决方案,但它不是很优雅。

还有其他想法吗?

编辑:

这是一个安全的解决方案:

def changelist_view(self, request, extra_context=None):
    self.request = request
    try:
        return super(MyAdmin,self).changelist_view(request, extra_context=extra_context)
    finally:
        self.request = None

编辑2:

根本不是线程安全的!1 2 , ...

4

3 回答 3

3

每个扩展 admin.ModelAdmin 的类都有两个可以覆盖的函数:change_view 和 changelist_view。 change_view在编辑单个实例时changelist_view调用,在查看所有项目列表时调用。

这两个函数充当管理员的视图定义并包含页面的请求对象。这意味着在这两个函数中,您可以将请求存储为 的属性,self以使其可供从该视图调用的类中的其他函数访问。话虽如此,这样的事情应该可以工作:

from django.contrib import admin
class MyAdmin(admin.ModelAdmin):
list_display = (
    'full_uri',
)

readonly_fields = (
    'full_uri',
)

def change_view(self, request, object_id, form_url='', extra_context=None):
    # access the request object when in the change view
    self.request = request
    return super(MyAdmin, self).change_view(request, object_id, form_url=form_url, extra_context=extra_context)

def changelist_view(self, request, extra_context=None):
    # access the request object when in the list view
    self.request = request
    return super(MyAdmin,self).changelist_view(request, extra_context=extra_context)

def full_uri(self, obj):
    return u'<a href="{url}">{url}'.format(
        # access the request object through self.request, as set by the two view functions
        url = self.request.build_absolute_uri(reverse('view_name', args=(obj.pk, )))
    )
full_uri.allow_tags = True
于 2013-03-12T21:52:04.643 回答
1

我想我找到了一种以线程安全的方式执行此操作的方法,在里面创建一个函数get_list_display

def get_list_display(self, request):

   def link_to_view(obj):
        return u'<a href="{url}">{url}'.format(
            url = request.build_absolute_uri(reverse('view_name', args=(obj, )))
        )
    token_access_link.short_description = _('link')
    token_access_link.allow_tags = True

    return (
        link_to_view,
    )
于 2013-03-14T13:17:47.117 回答
0

如果我正确理解了这个问题,您只需要访问尚未发送的函数中的请求对象吗?

如果是这样,我发现django-globals是最有帮助的,因为它提供了对当前请求和用户的通用访问(默认情况下应该可以像在烧瓶中一样访问!)

pip install django-globals

设置.py

INSTALLED_APPS = [
   ...
   'django_globals'
]
MIDDLEWARE_CLASSES = [
    ...
    'django_globals.middleware.Global'
]

视图.py

from django_globals import globals as djglobals

def myfunc():
    djglobals.user
    djglobals.request
于 2016-04-13T04:34:28.727 回答