00
:
00
:
00
:
00
•Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

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 oggetti
  • change_<modello> – permesso di modificare oggetti
  • delete_<modello> – permesso di eliminare oggetti
  • view_<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.