Djangoの管理者は、「変更するアイテムの選択」ページにあるリンクをdisableして、ユーザーがどこにもアイテムを編集できないようにします。 (このリストでユーザーが実行できることを、ドロップダウンアクションのセットに制限します-フィールドの実際の編集はありません)。
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
編集するリンクなしでオブジェクトリストを取得する方法はありますか?
リストとしてのみLog Viewerが必要でした。
私はそれをこのように機能させました:
_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, )
_
それは、両方の答えの混合のようなものです。
self.list_display_links = ()
だけを実行すると、リンクが表示されます。とにかく、_template-tag
_コード(templatetags/admin_list.py)が再度チェックして、リストが空かどうかを確認します。
これを適切に行うには、2つのステップが必要です。
2番目の部分は重要です。これを行わない場合でも、URLを直接入力することで、人々は引き続き変更ビューにアクセスできます(おそらく望まないでしょう)。これは、OWASPが "Insecure Direct Object Reference" と呼んでいるものと密接に関連しています。
この回答の一部として、示されているすべての機能を提供するために使用できるReadOnlyMixin
クラスを作成します。
Django 1.7はこれを本当に簡単にします:list_display_links
をNone
に設定するだけです。
class ReadOnlyMixin(): # Add inheritance from "object" if using Python 2
list_display_links = None
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,)
これにより、ミックスインが使いやすくなります。デフォルトでは編集リンクが非表示になりますが、特定の管理ビューで必要な場合は、リンクを元に戻すことができます。
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)
これもカスタマイズ可能です。enable_change_view
をTrue
に切り替えることで、詳細ページをオンに戻すことができます。
最後に、ユーザーが新しいアイテムを追加または削除しないようにするために、次のメソッドをオーバーライドすることができます。
def has_add_permission(self, request):
return False
def has_delete_permission(self, request, obj=None):
return False
これらの変更により:
/add
を追加して、ユーザーがアイテムを直接追加できないようにします最後に、actions
パラメータを変更して、「選択した項目を削除items」アクションを削除できます。
これが完成したミックスインです:
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
Django 1.7以降では、
class HitAdmin(admin.ModelAdmin):
list_display_links = None
ユーザー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'))
モデル管理セットで:
list_display_links = (None,)
それでうまくいくはずです。 (とにかく1.1.1で動作します。)
ドキュメントへのリンク: list_display_links
注意事項として、changelist_viewを変更できます。
class SomeAdmin(admin.ModelAdmin):
def changelist_view(self, request, extra_context=None):
self.list_display_links = (None, )
return super(SomeAdmin, self).changelist_view(request, extra_context=None)
これは私にとってはうまくいきます。
これを行うためのサポートされている方法はありません。
コードを見ると、何も設定しなければ、自動的にModelAdmin.list_display_links
が最初の要素に設定されるようです。したがって、最も簡単な方法は、ModelAdmin
サブクラスの__init__
メソッドをオーバーライドして、初期化時にその属性の設定を解除することです。
class HitAdmin(admin.ModelAdmin):
list_display = ('user','ip','user_agent','hitcount')
search_fields = ('ip','user_agent')
date_hierarchy = 'created'
def __init__(self, *args, **kwargs):
super(HitAdmin, self).__init__(*args, **kwargs)
self.list_display_links = []
非常に大ざっぱなテストの後、これはうまくいくようです。ただし、他の場所で問題が発生しないことや、Djangoの将来の変更によって問題が発生しないことは保証できません。
コメントの後に編集:
ソースにパッチを当てる必要はありません、これはうまくいくでしょう:
def __init__(self, *args, **kwargs):
if self.list_display_links:
unset_list_display = True
else:
unset_list_display = False
super(HitAdmin, self).__init__(*args, **kwargs)
if unset_list_display:
self.list_display_links = []
しかし、Djangoにパッチが受け入れられるかどうかは非常に疑わしいものです。これは、現時点でコードが明示的に行っていることを壊してしまうためです。
書くだけ list_display_links = None
管理者
Django 1.6.2を使用すると、次のようになります。
class MyAdmin(admin.ModelAdmin):
def get_list_display_links(self, request, list_display):
return []
自動生成されたリンクはすべて非表示になります。
Djangoのより「最近の」バージョンでは、少なくとも1.9以降、管理クラスの追加、変更、削除の権限を簡単に決定できます。 Django管理ドキュメント を参照してください。次に例を示します。
@admin.register(Object)
class Admin(admin.ModelAdmin):
def has_add_permission(self, request):
return False
def has_change_permission(self, request, obj=None):
return False
def has_delete_permission(self, request, obj=None):
return False
ridiculouslyハックすることもできます(_init
_のオーバーライドで大騒ぎしたくない場合)そして、基本的に次のような最初の要素の値を提供します。
_</a>My non-linked value<a>
_
私は知っています、あまりきれいではありませんが、マークアップを変更するだけなので、他の場所で何かを壊す心配は少ないでしょう。
これがどのように機能するかについてのサンプルコードは次のとおりです:
_class HitAdmin(admin.ModelAdmin):
list_display = ('user_no_link','ip','user_agent','hitcount')
def user_no_link(self, obj):
return u'</a>%s<a>' % obj
user_no_link.allow_tags = True
user_no_link.short_description = "user"
_
補足:return u'%s' % obj.get_full_name()
を返すことで、出力を読みやすくすることもできます(リンクにしたくないため)。
Get list_display_linksメソッドとアクションをNoneにオーバーライドします。
class ChangeLogAdmin(admin.ModelAdmin):
actions = None
list_display = ('asset', 'field', 'before_value', 'after_value', 'operator', 'made_at')
fieldsets = [
(None, {'fields': ()}),
]
def __init__(self, model, admin_site):
super().__init__(model, admin_site)
def get_list_display_links(self, request, list_display):
super().get_list_display_links(request, list_display)
return None