Django mit get_user_model vs settings.AUTH_USER_MODEL

91

Lesen der Django-Dokumentation:

get_user_model ()

Anstatt direkt auf Benutzer zu verweisen, sollten Sie das Benutzermodell mit django.contrib.auth.get_user_model () referenzieren. Diese Methode gibt das aktuell aktive Benutzermodell zurück - das benutzerdefinierte Benutzermodell, falls eines angegeben ist, oder den Benutzer anderweitig.

Wenn Sie einen Fremdschlüssel oder viele-zu-viele-Beziehungen zum Benutzermodell definieren, sollten Sie das benutzerdefinierte Modell mit der Einstellung AUTH_USER_MODEL angeben.

Ich bin mit dem obigen Text verwechselt. Soll ich das machen:

author = models.ForeignKey(settings.AUTH_USER_MODEL)

oder dieses...

author = models.ForeignKey(get_user_model())

Beide scheinen zu funktionieren.

Prometheus
quelle

Antworten:

81

Mit settings.AUTH_USER_MODELwird der Abruf der tatsächlichen Modellklasse verzögert, bis alle Apps geladen sind. get_user_modelwird versuchen, die Modellklasse abzurufen, sobald Ihre App zum ersten Mal importiert wird.

get_user_modelkann nicht garantieren, dass das UserModell bereits in den App-Cache geladen ist. Es könnte in Ihrem spezifischen Setup funktionieren, aber es ist ein Hit-and-Miss-Szenario. Wenn Sie einige Einstellungen ändern (z. B. die Reihenfolge von INSTALLED_APPS), wird der Import möglicherweise unterbrochen, und Sie müssen zusätzliche Zeit für das Debuggen aufwenden.

settings.AUTH_USER_MODEL Übergibt eine Zeichenfolge als Fremdschlüsselmodell. Wenn der Abruf der Modellklasse zum Zeitpunkt des Imports dieses Fremdschlüssels fehlschlägt, wird der Abruf verzögert, bis alle Modellklassen in den Cache geladen sind.

knbk
quelle
6
Konkret können bei Modellen zirkuläre Importprobleme auftreten.ForeignKey (get_user_model ())
Chris Clark
1
In diesem Abschnitt der Dokumentation heißt es: "Im Allgemeinen sollten Sie das Benutzermodell mit der AUTH_USER_MODELEinstellung im Code referenzieren, die beim Import ausgeführt wird. Funktioniert get_user_model()nur, wenn Django alle Modelle importiert hat."
Hamish Downer
7
Konkret also in Funktionen (Ansichten, Modell- / Serializer- / Formularmethoden) get_user_model()für Klassenattribute verwenden AUTH_USER_MODEL?
Nick T
51

Neu seit Django 1.11.

Seit Django 1.11 können Sie get_user_model()in beiden Fällen verwenden! Wenn Sie sich also nicht weiter darum kümmern möchten, nehmen Sie es einfach.

"in beiden Fällen" bedeutet: wenn Sie das Benutzermodell für den Zugriff auf seine Attribute benötigen sowie eine ForeignKey / ManyToMany-Beziehung definieren möchten.

Aus dem Changelog :

get_user_model () kann jetzt beim Import aufgerufen werden, auch in Modulen, die Modelle definieren.

Also ... gibt es noch einen Grund zu verwenden settings.AUTH_USER_MODEL? Nun, die Dokumente empfehlen immer noch diesettings.AUTH_USER_MODEL (was eine Zeichenfolge ist) zum Definieren von Beziehungen, ohne jedoch einen expliziten Grund anzugeben. Könnte für die Leistung von Vorteil sein, scheint aber nicht viel zu bedeuten.

Codebeispiel:

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
quelle
Vielen Dank für den Hinweis, dass get_user_model()dies beim Import aufgerufen werden kann. Django rät jedoch weiterhin, dass Benutzer Fremdschlüssel- und Viele-zu-Viele-Beziehungen mit AUTH_USER_MODEL definieren
kevins
2
Vielen Dank, dass Sie auf diese Empfehlung hingewiesen haben. Irgendwie habe ich sie beim Schreiben der Antwort übersehen, aber jetzt habe ich sie gefunden. Ich habe versucht, dies in die Antwort zu integrieren (immer noch positiv get_user_model, besonders für Leser, die über die Unterscheidung verwirrt sind)
Ilja
5

Seit Django 1.11 get_user_model()verwendet tatsächlich 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
quelle
-11

Eine Möglichkeit, auf das Standardbenutzermodell zurückzugreifen, wenn AUTH_USER_MODEL nicht festgelegt ist:

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

USER_MODEL = getattr(settings, 'AUTH_USER_MODEL', User)
synw
quelle
7
AUTH_USER_MODELhat bereits eine Standardeinstellung, daher wird diese immer festgelegt.
Knbk
4
settings.AUTH_USER_MODEL ist auch eine Zeichenfolge und Ihr Fallback Userist ein Modell
Matt