Permessi e Gruppi
Django include un sistema di permessi flessibile che permette di controllare lâaccesso alle funzionalita dellâapplicazione. I permessi possono essere assegnati a singoli utenti o a gruppi di utenti.
Permessi Predefiniti
Django crea automaticamente quattro permessi per ogni modello registrato:
add_<modello>â permesso di creare oggettichange_<modello>â permesso di modificare oggettidelete_<modello>â permesso di eliminare oggettiview_<modello>â permesso di visualizzare oggetti
from django.contrib.auth.models import User, Permission
utente = User.objects.get(username='mario')
# Verificare un permesso
utente.has_perm('myapp.add_articolo') # True o False
utente.has_perm('myapp.change_articolo') # True o False
# Assegnare un permesso
permesso = Permission.objects.get(codename='add_articolo')
utente.user_permissions.add(permesso)
# Rimuovere un permesso
utente.user_permissions.remove(permesso)
# Verificare piu permessi contemporaneamente
utente.has_perms(['myapp.add_articolo', 'myapp.change_articolo'])
Nota: i superuser hanno automaticamente tutti i permessi.
Gruppi
I gruppi permettono di assegnare un insieme di permessi a piu utenti contemporaneamente:
from django.contrib.auth.models import Group, Permission
# Creare un gruppo
redattori = Group.objects.create(name='Redattori')
# Aggiungere permessi al gruppo
permessi = Permission.objects.filter(
codename__in=['add_articolo', 'change_articolo', 'view_articolo']
)
redattori.permissions.set(permessi)
# Aggiungere un utente al gruppo
utente = User.objects.get(username='mario')
utente.groups.add(redattori)
# Verificare l'appartenenza a un gruppo
utente.groups.filter(name='Redattori').exists() # True
# L'utente eredita i permessi del gruppo
utente.has_perm('myapp.add_articolo') # True
Permessi Personalizzati
Puoi definire permessi personalizzati nella classe Meta di un modello:
# models.py
from django.db import models
class Articolo(models.Model):
titolo = models.CharField(max_length=200)
contenuto = models.TextField()
pubblicato = models.BooleanField(default=False)
class Meta:
permissions = [
('pubblica_articolo', 'Puo pubblicare articoli'),
('archivia_articolo', 'Puo archiviare articoli'),
('evidenzia_articolo', 'Puo mettere in evidenza articoli'),
]
Dopo aver aggiunto i permessi, esegui le migrazioni per crearli nel database:
# python manage.py makemigrations
# python manage.py migrate
Decoratore @permission_required
Usa il decoratore @permission_required per proteggere le viste:
from django.contrib.auth.decorators import permission_required
@permission_required('myapp.add_articolo')
def crea_articolo(request):
# Solo utenti con il permesso possono accedere
return render(request, 'crea_articolo.html')
@permission_required('myapp.pubblica_articolo', raise_exception=True)
def pubblica_articolo(request, pk):
# raise_exception=True restituisce 403 invece di redirect al login
articolo = Articolo.objects.get(pk=pk)
articolo.pubblicato = True
articolo.save()
return redirect('lista_articoli')
@permission_required(
['myapp.change_articolo', 'myapp.pubblica_articolo'],
raise_exception=True
)
def modifica_e_pubblica(request, pk):
# Richiede piu permessi contemporaneamente
pass
PermissionRequiredMixin per Class-Based Views
Per le class-based views, usa PermissionRequiredMixin:
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.views.generic import CreateView
from .models import Articolo
class CreaArticoloView(PermissionRequiredMixin, CreateView):
model = Articolo
fields = ['titolo', 'contenuto']
permission_required = 'myapp.add_articolo'
raise_exception = True
Permessi nei Template
Nei template puoi verificare i permessi dellâutente con la variabile perms:
# {% if perms.myapp.add_articolo %}
# <a href="{% url 'crea_articolo' %}">Nuovo Articolo</a>
# {% endif %}
#
# {% if perms.myapp.pubblica_articolo %}
# <button>Pubblica</button>
# {% endif %}
#
# {% if perms.myapp.delete_articolo %}
# <button class="btn-danger">Elimina</button>
# {% endif %}
Verifiche Programmatiche nelle View
Puoi verificare i permessi direttamente nel codice della view:
from django.http import HttpResponseForbidden
def gestisci_articolo(request, pk):
articolo = Articolo.objects.get(pk=pk)
if request.user.has_perm('myapp.change_articolo'):
# Mostra il form di modifica
return render(request, 'modifica_articolo.html', {'articolo': articolo})
elif request.user.has_perm('myapp.view_articolo'):
# Mostra solo la visualizzazione
return render(request, 'dettaglio_articolo.html', {'articolo': articolo})
else:
return HttpResponseForbidden("Non hai i permessi necessari.")
Creare Permessi via Codice
Oltre alla classe Meta, puoi creare permessi programmaticamente:
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
from .models import Articolo
content_type = ContentType.objects.get_for_model(Articolo)
permesso = Permission.objects.create(
codename='esporta_articolo',
name='Puo esportare articoli',
content_type=content_type,
)
Conclusione
Il sistema di permessi e gruppi di Django offre un controllo granulare sullâaccesso alle funzionalita dellâapplicazione. I permessi predefiniti coprono le operazioni CRUD, mentre i permessi personalizzati permettono di modellare qualsiasi logica di autorizzazione. Combinati con i gruppi, i decoratori e le verifiche nei template, rendono semplice implementare un sistema di autorizzazione completo e manutenibile.