Django usando get_user_model vs settings.AUTH_USER_MODEL

99

Leyendo la documentación de Django:

get_user_model ()

En lugar de referirse al usuario directamente, debe hacer referencia al modelo de usuario usando django.contrib.auth.get_user_model (). Este método devolverá el modelo de usuario actualmente activo: el modelo de usuario personalizado si se especifica uno, o el usuario de lo contrario.

Cuando define una clave externa o relaciones de muchos a muchos con el modelo de usuario, debe especificar el modelo personalizado mediante la configuración AUTH_USER_MODEL.

Estoy confundido con el texto anterior. Debería estar haciendo esto:

author = models.ForeignKey(settings.AUTH_USER_MODEL)

o esto...

author = models.ForeignKey(get_user_model())

Ambos parecen funcionar.

Prometeo
fuente

Respuestas:

89

El uso settings.AUTH_USER_MODELretrasará la recuperación de la clase de modelo real hasta que se carguen todas las aplicaciones. get_user_modelintentará recuperar la clase de modelo en el momento en que se importe su aplicación por primera vez.

get_user_modelno puede garantizar que el Usermodelo ya esté cargado en la caché de la aplicación. Puede que funcione en su configuración específica, pero es un escenario impredecible. Si cambia alguna configuración (por ejemplo, el orden de INSTALLED_APPS), es muy posible que se interrumpa la importación y tendrá que dedicar más tiempo a depurar.

settings.AUTH_USER_MODEL pasará una cadena como modelo de clave externa, y si la recuperación de la clase de modelo falla en el momento en que se importa esta clave externa, la recuperación se retrasará hasta que todas las clases de modelo se carguen en la caché.

knbk
fuente
7
Concretamente, puede encontrarse con problemas de importación circular con modelos. ForeignKey (get_user_model ())
Chris Clark
2
Esta sección de los documentos dice "En general, debes hacer referencia al modelo de usuario con la AUTH_USER_MODELconfiguración en el código que se ejecuta en el momento de la importación. get_user_model()Solo funciona una vez que Django ha importado todos los modelos".
Hamish Downer
7
Entonces, concretamente, en funciones (vistas, modelo / serializador / métodos de formulario), ¿uso get_user_model(), para uso de atributos de clase AUTH_USER_MODEL?
Nick T
53

Nuevo desde Django 1.11.

¡Desde Django 1.11 puedes usar get_user_model()en ambos casos! Entonces, si no quiere preocuparse más por eso, simplemente tómelo.

"en ambos casos" significa: si necesita el modelo de usuario para acceder a sus atributos, así como si desea definir una relación ForeignKey / ManyToMany.

Desde el registro de cambios :

get_user_model () ahora se puede llamar en el momento de la importación, incluso en módulos que definen modelos.

entonces ... ¿todavía hay una razón para usar settings.AUTH_USER_MODEL? Bueno, los documentos todavía recomiendan settings.AUTH_USER_MODEL(que es una cadena) para definir relaciones, pero sin dar una razón explícita. Puede ser beneficioso para el rendimiento, pero no parece importar mucho.

Ejemplo de código:

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!
        ...
    )
Ilja
fuente
Gracias por señalar que get_user_model()se puede llamar en el momento de la importación; sin embargo, Django todavía aconseja que los usuarios definan relaciones de clave externa y de muchos a muchos usando AUTH_USER_MODEL
kevins
2
gracias por señalar esta recomendación, de alguna manera la pasé por alto al escribir la respuesta, pero ahora la encontré. Traté de integrar este principio en la respuesta (sigue favoreciendo get_user_model, especialmente para los lectores que están confundidos acerca de la distinción)
Ilja
7

Desde Django 1.11, en get_user_model()realidad usa 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
        )
Murey Tasroc
fuente
0

settings.AUTH_USER_MODEL devuelve una cadena (la ubicación del modelo de usuario), por ejemplo, 'user_accounts.User'

get_user_model () devuelve la clase de modelo ACTUAL, no una cadena.

Entonces, en los casos en los que necesite el modelo de usuario, use get_user_model (). Si necesita su ubicación (módulo.modelo como una cadena), use la configuración.AUTH_USER_MODEL.

ImportError
fuente
-11

Una forma de recurrir al modelo de usuario predeterminado si AUTH_USER_MODEL no está configurado:

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

USER_MODEL = getattr(settings, 'AUTH_USER_MODEL', User)
sincronizar
fuente
7
AUTH_USER_MODELya tiene un valor predeterminado, por lo que siempre estará configurado.
knbk
4
settings.AUTH_USER_MODEL también es una cadena y su respaldo Useres un modelo
Matt