これが、Django1.0.2を変更して「表示」権限を追加した方法です。申し訳ありませんが、利用可能な差分はありません。
[X]1.デフォルトの権限リストに「view」を追加しました
#./contrib/auth/management/__init__.py
def _get_all_permissions(opts):
"Returns (codename, name) for all permissions in the given opts."
perms = []
for action in ('add', 'change', 'delete', 'view'):
perms.append((_get_permission_codename(action, opts), u'Can %s %s' % (action, opts.verbose_name_raw)))
return perms + list(opts.permissions)
[X]2.「表示」権限がすべてのモデルに追加されていることをテストします
run manage.py syncdb
auth_permissionsテーブルのすべてのテーブルに表示権限が追加されたことを確認しました
[X]3.デフォルトのモデルクラスに「get_view_permission」を追加します。
モデルクラスにget_view_permissionを追加しました。これは、ファイル./db/models/options.pyにあります。これは、次のステップでadminクラスによって使用されます。
def get_view_permission(self):
return 'view_%s' % self.object_name.lower()
[X]4.デフォルトの管理クラスに「has_view_permission」を追加します
一貫性を保つために、システムに「has_view_permission」を追加します。contrib / admin/options.pyのどこかにあるはずです。ユーザーが変更権限を持っているかどうかを確認すると、表示権限が自動的に暗示されます。
# /contrib/admin/options.py
# Added has_view_permissions
def has_view_permission(self, request, obj=None):
"""
Returns True if the given request has permission to change or view
the given Django model instance.
If `obj` is None, this should return True if the given request has
permission to change *any* object of the given type.
"""
opts = self.opts
return self.has_change_permission(request, obj) or \
request.user.has_perm(opts.app_label + '.' + opts.get_view_permission())
# modified get_model_perms to include 'view' too.
# No idea where this may be used, but trying to stay consistent
def get_model_perms(self, request):
"""
Returns a dict of all perms for this model. This dict has the keys
``add``, ``change``, and ``delete`` and ``view`` mapping to the True/False
for each of those actions.
"""
return {
'add': self.has_add_permission(request),
'change': self.has_change_permission(request),
'delete': self.has_delete_permission(request),
'view': self.has_view_permission(request),
}
# modified response_add function to return the user to the mode list
# if they added a unit and have view rights
...
else:
self.message_user(request, msg)
# Figure out where to redirect. If the user has change permission,
# redirect to the change-list page for this object. Otherwise,
# redirect to the admin index.
#if self.has_change_permission(request, None):
if self.has_change_permission(request, None) or self.has_view_permission(request, None):
post_url = '../'
else:
post_url = '../../../'
return HttpResponseRedirect(post_url)
# modified the change_view function so it becomes the details
# for users with view permission
#if not self.has_change_permission(request, obj):
if not (self.has_change_permission(request, obj) or (self.has_view_permission(request, obj) and not request.POST)):
raise PermissionDenied
# modified the changelist_view function so it shows the list of items
# if you have view permissions
def changelist_view(self, request, extra_context=None):
"The 'change list' admin view for this model."
from django.contrib.admin.views.main import ChangeList, ERROR_FLAG
opts = self.model._meta
app_label = opts.app_label
#if not self.has_change_permission(request, None):
if not (self.has_change_permission(request, None) or self.has_view_permission(request, None)):
raise PermissionDenied
[X] 5.ユーザーが表示権限を持っている場合は、デフォルトのテンプレートを更新してモデルを一覧表示します
contrib / admin / templates / admin/index.htmlのデフォルトテンプレートを変更しました。これは、代わりにファイルをローカルテンプレートディレクトリにコピーすることでも処理できます。両方に変更を加えたので、後のアップグレードで変更が上書きされた場合にコピーがあります。
{% for model in app.models %}
<tr>
{% if model.perms.change %}
<th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
{% else %}
{% if model.perms.view %}
<th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
{% else %}
<th scope="row">{{ model.name }}</th>
{% endif %}
{% endif %}
[X]6.ユーザーがモデルを「表示」できるが「変更」できないことを確認する
見つかったcontrib/admin / templatetags / admin_modify.pyは、保存/保存および続行ボタンが表示されるかどうかを制御しているようです。コンテキストと権限をチェックするために、「保存」フィールドをデフォルトの常にTrueから変更しました。ユーザーが変更または追加の権限を持っている場合、ユーザーは保存できるはずです。
'show_save': (change and context['has_change_permission']) or (context['add'] and context['has_add_permission'])
[X] 7.ユーザーがアイテムを表示している場合は、[保存して別のアイテムを追加]ボタンを削除します
contrib / admin / templatetags/admin_modify.pyを再度変更しました。'save_as'の意味がわからないので、何かを壊したのかもしれませんが、うまくいくようです。
#'show_save_and_add_another': context['has_add_permission'] and
# not is_popup and (not save_as or context['add']) ,
'show_save_and_add_another': not is_popup and
(( change and context['has_change_permission']) or (context['add'] and context['has_add_permission']))
and
(not save_as or context['add']),
[X] 8.フォームを読み取り専用にするために、「表示」権限を変更します
ユーザーが「表示」権限と「変更」権限を持っている場合は、何もしません。ビューのオーバーライドを変更します。
ユーザーが「変更」なしで「表示」権限を持っている場合は、デフォルトのフォームを変更し、フォーム要素にDISABLEDまたはREADONLY属性を追加します。すべてのブラウザがこれをサポートしているわけではありませんが、私の目的では、ユーザーに適切なブラウザを使用するように要求できます。 無効/読み取り専用の例
すべてのブラウザが「読み取り専用」を尊重しているわけではないため、一部のコントロールを読み取り専用に設定し、他のコントロールを無効に設定していることがわかりました。これにより、ユーザーは必要に応じてテキストコントロールからデータをコピーできます。
#/django/contrib/admin/templates/admin/change_form.html
{# JavaScript for prepopulated fields #}
{% prepopulated_fields_js %}
</div>
</form></div>
{% if has_view_permission and not has_change_permission %}
<script type="text/javascript">
jQuery('input:text').attr('readonly', 'readonly');
jQuery('textarea').attr('readonly', 'readonly');
jQuery('input:checkbox').attr('disabled', true);
jQuery('select').attr('disabled', true);
jQuery('.add-another').hide();
</script>
{% endif %}