tho*_*mad 43 python django modeladmin django-admin
在Django的管理员中,我想禁用 "选择要更改的项目"页面上提供的链接,以便用户无法去任何地方编辑项目.(我将限制用户可以对此列表执行的操作到一组下拉操作 - 没有实际编辑字段).
我看到Django能够选择显示链接的字段,但是,我看不出我怎么也没有.
class HitAdmin(admin.ModelAdmin):
list_display = ('user','ip','user_agent','hitcount')
search_fields = ('ip','user_agent')
date_hierarchy = 'created'
list_display_links = [] # doesn't work, goes to default
Run Code Online (Sandbox Code Playgroud)
任何想法如何获取我的对象列表没有任何链接编辑?
Fed*_*ico 60
我只想将日志查看器作为列表.
我得到它像这样工作:
class LogEntryAdmin(ModelAdmin):
actions = None
list_display = (
'action_time', 'user',
'content_type', 'object_repr',
'change_message')
search_fields = ['=user__username', ]
fieldsets = [
(None, {'fields':()}),
]
def __init__(self, *args, **kwargs):
super(LogEntryAdmin, self).__init__(*args, **kwargs)
self.list_display_links = (None, )
Run Code Online (Sandbox Code Playgroud)
它是两种答案之间的混合.
如果您这样做self.list_display_links = (),它将显示链接,无论如何,因为template-tag代码(templatetags/admin_list.py)再次检查以查看列表是否为空.
sim*_*igh 32
正确执行此操作需要两个步骤:
第二部分很重要:如果你不这样做,那么人们仍然可以通过直接输入URL来访问更改视图(这可能是你不想要的).这与OWASP所称的"不安全直接对象参考"密切相关.
作为这个答案的一部分,我将构建一个ReadOnlyMixin可用于提供所有功能的类.
Django的1.7使这真的很简单:您只需设置list_display_links到None.
class ReadOnlyMixin(): # Add inheritance from "object" if using Python 2
list_display_links = None
Run Code Online (Sandbox Code Playgroud)
Django 1.6(大概早些时候)并没有这么简单.这个问题的很多答案已经建议覆盖__init__以便list_display_links在构造对象之后进行设置,但是这使得重用更加困难(我们只能覆盖构造函数一次).
我认为更好的选择是覆盖Django的get_list_display_links方法如下:
def get_list_display_links(self, request, list_display):
"""
Return a sequence containing the fields to be displayed as links
on the changelist. The list_display parameter is the list of fields
returned by get_list_display().
We override Django's default implementation to specify no links unless
these are explicitly set.
"""
if self.list_display_links or not list_display:
return self.list_display_links
else:
return (None,)
Run Code Online (Sandbox Code Playgroud)
这使得我们的mixin易于使用:它默认隐藏编辑链接,但允许我们在特定管理视图需要时将其添加回来.
我们可以通过覆盖change_view方法来更改详细信息页面(更改视图)的行为.这是Chris Pratt建议的技术的扩展,它自动找到正确的页面:
enable_change_view = False
def change_view(self, request, object_id, form_url='', extra_context=None):
"""
The 'change' admin view for this model.
We override this to redirect back to the changelist unless the view is
specifically enabled by the "enable_change_view" property.
"""
if self.enable_change_view:
return super(ReportMixin, self).change_view(
request,
object_id,
form_url,
extra_context
)
else:
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
opts = self.model._meta
url = reverse('admin:{app}_{model}_changelist'.format(
app=opts.app_label,
model=opts.model_name,
))
return HttpResponseRedirect(url)
Run Code Online (Sandbox Code Playgroud)
再次这是可自定义的 - 通过切换enable_change_view到True您可以重新打开详细信息页面.
最后,您可能希望覆盖以下方法,以防止人们添加或删除新项目.
def has_add_permission(self, request):
return False
def has_delete_permission(self, request, obj=None):
return False
Run Code Online (Sandbox Code Playgroud)
这些变化将:
/add到URL 直接添加项目最后,您可以通过修改参数来删除"删除所选项目 "操作actions.
这是完成的mixin:
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
class ReadOnlyMixin(): # Add inheritance from "object" if using Python 2
actions = None
enable_change_view = False
def get_list_display_links(self, request, list_display):
"""
Return a sequence containing the fields to be displayed as links
on the changelist. The list_display parameter is the list of fields
returned by get_list_display().
We override Django's default implementation to specify no links unless
these are explicitly set.
"""
if self.list_display_links or not list_display:
return self.list_display_links
else:
return (None,)
def change_view(self, request, object_id, form_url='', extra_context=None):
"""
The 'change' admin view for this model.
We override this to redirect back to the changelist unless the view is
specifically enabled by the "enable_change_view" property.
"""
if self.enable_change_view:
return super(ReportMixin, self).change_view(
request,
object_id,
form_url,
extra_context
)
else:
opts = self.model._meta
url = reverse('admin:{app}_{model}_changelist'.format(
app=opts.app_label,
model=opts.model_name,
))
return HttpResponseRedirect(url)
def has_add_permission(self, request):
return False
def has_delete_permission(self, request, obj=None):
return False
Run Code Online (Sandbox Code Playgroud)
Chr*_*att 18
作为上述评论中提到的用户,omat,任何简单删除链接的尝试都不会阻止用户手动访问更改页面.但是,这也很容易补救:
class MyModelAdmin(admin.ModelAdmin)
# Other stuff here
def change_view(self, request, obj=None):
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
return HttpResponseRedirect(reverse('admin:myapp_mymodel_changelist'))
Run Code Online (Sandbox Code Playgroud)
Bla*_*ise 15
在Django 1.7及更高版本中,你可以做到
class HitAdmin(admin.ModelAdmin):
list_display_links = None
Run Code Online (Sandbox Code Playgroud)
在您的模型管理集中:
list_display_links = (None,)
Run Code Online (Sandbox Code Playgroud)
应该这样做.(无论如何都适用于1.1.1.)
链接到docs:list_display_links