我正在尝试在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
并存储请求localy,但这不是thread safe。
我也试过this解决方案,但它不是很优雅。
还有其他想法吗?
修改
这是一个安全的解决方案:
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
EDIT2:
答案 0 :(得分: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
答案 1 :(得分: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,
)
答案 2 :(得分:0)
如果我已正确理解了这个问题,您只需要在尚未发送的函数中访问请求对象吗?
如果是这样,我发现django-globals最有帮助,因为它提供了对当前请求和用户的普遍访问权限(默认情况下应该可以访问,如烧瓶!)
pip install django-globals
settings.py
INSTALLED_APPS = [
...
'django_globals'
]
MIDDLEWARE_CLASSES = [
...
'django_globals.middleware.Global'
]
view.py
from django_globals import globals as djglobals
def myfunc():
djglobals.user
djglobals.request