Django utilizza get_user_model rispetto alle impostazioni.AUTH_USER_MODEL


98

Leggere la documentazione di Django:

get_user_model ()

Invece di fare riferimento direttamente all'Utente, dovresti fare riferimento al modello utente usando django.contrib.auth.get_user_model (). Questo metodo restituirà il modello utente attualmente attivo: il modello utente personalizzato se specificato o altrimenti l'utente.

Quando si definisce una chiave esterna o relazioni molti-a-molti per il modello utente, è necessario specificare il modello personalizzato utilizzando l'impostazione AUTH_USER_MODEL.

Sono confuso con il testo sopra. Dovrei farlo:

author = models.ForeignKey(settings.AUTH_USER_MODEL)

o questo...

author = models.ForeignKey(get_user_model())

Entrambi sembrano funzionare.

Risposte:


88

L'utilizzo settings.AUTH_USER_MODELritarderà il recupero della classe del modello effettiva fino al caricamento di tutte le app. get_user_modeltenterà di recuperare la classe del modello nel momento in cui l'app viene importata per la prima volta.

get_user_modelnon può garantire che il Usermodello sia già caricato nella cache dell'app. Potrebbe funzionare nella tua configurazione specifica, ma è uno scenario incostante. Se modifichi alcune impostazioni (ad esempio l'ordine di INSTALLED_APPS) potrebbe benissimo interrompere l'importazione e dovrai dedicare più tempo al debug.

settings.AUTH_USER_MODEL passerà una stringa come modello di chiave esterna e se il recupero della classe del modello fallisce al momento dell'importazione di questa chiave esterna, il recupero verrà ritardato fino a quando tutte le classi del modello non saranno caricate nella cache.


7
In concreto, puoi incorrere in problemi di importazione circolare con i modelli.ForeignKey (get_user_model ())
Chris Clark

2
Questa sezione della documentazione dice "In generale, dovresti fare riferimento al modello utente con l' AUTH_USER_MODELimpostazione nel codice che viene eseguita al momento dell'importazione. get_user_model()Funziona solo dopo che Django ha importato tutti i modelli."
Hamish Downer

7
Quindi, concretamente, nelle funzioni (viste, metodi modello / serializzatore / modulo), usa get_user_model(), per gli attributi di classe AUTH_USER_MODEL?
Nick T

53

Novità da Django 1.11.

Da Django 1.11 puoi usare get_user_model()in entrambi i casi! Quindi se non vuoi preoccuparti ulteriormente, prendilo.

"in entrambi i casi" significa: se hai bisogno del modello utente per accedere ai suoi attributi, così come se vuoi definire una relazione ForeignKey / ManyToMany.

Dal changelog :

get_user_model () ora può essere chiamato al momento dell'importazione, anche nei moduli che definiscono i modelli.

quindi ... c'è ancora un motivo per usarlo settings.AUTH_USER_MODEL? Ebbene, i documenti consigliano ancora settings.AUTH_USER_MODEL(che è una stringa) per definire le relazioni, ma senza fornire una ragione esplicita. Potrebbe essere utile per le prestazioni, ma non sembra avere molta importanza.

Esempio di codice:

from django.db import models
from django.contrib.auth import get_user_model
...
    ...
    user = models.ForeignKey(
        get_user_model(),
        null=True, # explicitly set null, since it's required in django 2.x. - otherwise migrations will be incompatible later!
        ...
    )

Grazie per aver sottolineato che get_user_model()può essere chiamato al momento dell'importazione; tuttavia, Django consiglia comunque agli utenti di definire le relazioni di chiave esterna e molti-a-molti utilizzando AUTH_USER_MODEL
kevins

2
grazie per aver sottolineato questa raccomandazione, in qualche modo l'ho trascurata quando ho scritto la risposta, ma ora l'ho trovata. Ho provato a integrare questo nella risposta (ancora favorevole get_user_model, soprattutto per i lettori che sono confusi sulla distinzione)
Ilja

7

A partire da Django 1.11, get_user_model()utilizza attualmente settings.AUTH_USER_MODEL:

def get_user_model():
    """
    Return the User model that is active in this project.
    """
    try:
        return django_apps.get_model(settings.AUTH_USER_MODEL, require_ready=False)
    except ValueError:
        raise ImproperlyConfigured("AUTH_USER_MODEL must be of the form 'app_label.model_name'")
    except LookupError:
        raise ImproperlyConfigured(
            "AUTH_USER_MODEL refers to model '%s' that has not been installed" % settings.AUTH_USER_MODEL
        )

0

settings.AUTH_USER_MODEL restituisce una stringa (la posizione del modello utente) ad es. "user_accounts.User"

get_user_model () restituisce la classe del modello EFFETTIVA, non una stringa.

Quindi, nei casi in cui è necessario il modello utente, utilizzare get_user_model (). Se hai bisogno della sua posizione (module.model come stringa), usa le impostazioni.AUTH_USER_MODEL.


-11

Un modo per eseguire il fallback al modello utente predefinito se AUTH_USER_MODEL non è impostato:

from django.conf import settings
from django.contrib.auth.models import User

USER_MODEL = getattr(settings, 'AUTH_USER_MODEL', User)

7
AUTH_USER_MODELha già un valore predefinito, quindi sarà sempre impostato.
Knbk

4
Anche l'AUTH_USER_MODEL è una stringa e il tuo fallback Userè un modello
Matt
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.