Voici comment j'ai modifié Django 1.0.2 pour ajouter les permissions 'view'. Désolé, il n'y a pas de différence disponible.
[X] 1. Ajout de "view" à la liste des autorisations par défaut
#./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. Test de l'ajout de l'autorisation "view" à tous les modèles
run manage.py syncdb
J'ai confirmé que la permission d'affichage est maintenant ajoutée pour toutes les tables dans la table auth_permissions.
[X] 3. Ajouter "get_view_permission" à la classe de modèle par défaut.
Ajouté get_view_permission à la classe de modèle. Vous pouvez trouver ceci dans le fichier ./db/models/options.py Ceci est utilisé par la classe admin dans l'étape suivante.
def get_view_permission(self):
return 'view_%s' % self.object_name.lower()
[X] 4. Ajouter "has_view_permission" à la classe d'administration par défaut
Juste pour être cohérent, je vais ajouter "has_view_permission" au système. On dirait que ça devrait être quelque part dans contrib/admin/options.py . Je me suis assuré que si l'utilisateur a l'autorisation de modifier, alors les autorisations de visualisation sont automatiquement impliquées.
# /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. Mise à jour du modèle par défaut pour lister les modèles si l'utilisateur a le droit de les visualiser
J'ai modifié le modèle par défaut dans contrib/admin/templates/admin/index.html. Cela pourrait également être géré en copiant le fichier dans le répertoire local des modèles à la place. J'ai fait des changements dans les deux afin d'avoir une copie si une mise à jour ultérieure écrase mes changements.
{% 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. Confirmer que l'utilisateur peut "voir" mais pas "modifier" le modèle
Trouvé contrib/admin/templatetags/admin_modify.py semble contrôler l'apparition ou non des boutons "save / save and continue". J'ai modifié le champ "save", qui est par défaut toujours vrai, pour vérifier le contexte et les autorisations. L'utilisateur devrait être en mesure d'enregistrer s'il a des autorisations de modification ou d'ajout.
'show_save': (change and context['has_change_permission']) or (context['add'] and context['has_add_permission'])
[X] 7. Suppression du bouton "Enregistrer et ajouter un autre" si l'utilisateur visualise un élément.
Modifié à nouveau contrib/admin/templatetags/admin_modify.py. Je ne sais pas ce que signifie "save_as" et j'ai peut-être cassé quelque chose, mais cela semble fonctionner.
#'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. Modifier la permission "view" pour que le formulaire soit en lecture seule.
Si l'utilisateur a le droit de "voir" et de "modifier", alors ne faites rien. La modification a priorité sur la visualisation.
Si l'utilisateur a le droit de "visualiser" sans "modifier", modifiez les formulaires par défaut et ajoutez les attributs DISABLED ou READONLY aux éléments de formulaire. Tous les navigateurs ne prennent pas en charge cette fonctionnalité, mais pour mes besoins, je peux exiger que les utilisateurs utilisent le bon navigateur. Exemple de désactivation / lecture seule
Il s'est avéré que tous les navigateurs n'acceptent pas l'option "readonly", ce qui fait que certains contrôles sont en lecture seule et d'autres sont désactivés. Cela permet aux utilisateurs de copier les données des contrôles de texte si nécessaire.
#/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 %}