2013-07-04 12 views
6

Ich arbeite an einem Django 1.5-Projekt, und ich habe ein eigenes Benutzermodell (nennen wir es CustomUser). Eine andere App (SomeApp) muss auf dieses benutzerdefinierte Benutzermodell verweisen. Für die Zwecke der ForeignKey und so, sagt die Django-DokumentationDjango 1.5: Zugriff auf benutzerdefinierte Modellfelder in models.py

User = settings.AUTH_USER_MODEL 

jedoch einige Funktionen in SomeApp.models verwenden müssen zuzugreifen, was früher als User.objects bekannt gewesen wäre. Aber Benutzer ist jetzt eine Zeichenfolge und keine Klasse, also schlägt User.objects fehl. Die Alternative wäre

from django.contrib.auth import get_user_model 
User = get_user_model() 

werden, die in anderen Modulen funktioniert, aber wenn ich diese verwenden in models.py von SomeApp, Django löst einen Fehler:

ImproperlyConfigured("AUTH_USER_MODEL refers to model '%s' that has not been installed" % settings.AUTH_USER_MODEL)

Irgendwelche Ideen?

EDIT 1 - Traceback:

Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
    File "...\django-badger\badger\__init__.py", line 7, in <module> 
    from badger.models import Badge, Award, Progress 
    File "...\django-badger\badger\models.py", line 26, in <module> 
    User = get_user_model() 
    File "...\lib\site-packages\django\contrib\auth\__init__.py", line 127, in get_user_model 
    raise ImproperlyConfigured("AUTH_USER_MODEL refers to model '%s' that has not been installed" % settings.AUTH_USER_MODEL) 
ImproperlyConfigured: AUTH_USER_MODEL refers to model 'MyApp.AuthUser' that has not been installed 

EDIT 2 - INSTALLED_APPS Einstellungen:

INSTALLED_APPS = (
'django.contrib.auth', 
'django.contrib.contenttypes', 
'django.contrib.sessions', 
'django.contrib.sites', 
'django.contrib.messages', 
'django.contrib.staticfiles', 
'django.contrib.admin', 
'django.contrib.admindocs', 
'south', 
'MyApp', # this is where my user model is defined 
'SomeApp', # I try to use get_user_model() in this app's models.py; doesn't work. 
'social_auth', 
) 
+0

Können Sie volle Zurückverfolgungs posten? – jpic

+0

Wie haben Sie 'AUTH_USER_MODEL' in Ihren Einstellungen definiert? In welcher Anwendung ist der Benutzer und wie lautet der Klassenname? – matino

+0

@matino - ja, es ist in den Einstellungen definiert. get_user_model() funktioniert in allen anderen Dateien außer models.py. Mein benutzerdefiniertes Modell AuthUser in MeineAnw (in diesem Beispiel) definiert – askvictor

Antwort

0

Sie setzen müssen,

AUTH_USER_MODEL = "yourapp.CustomUser"

im settings.py. Dann wird die get_user_model() funktionieren. Es gibt eine saubere documentation available.

+0

Es ist schon. get_user_model() funktioniert in anderen Dateien außer models.py. – askvictor

+0

Überprüfen Sie die Reihenfolge Ihrer 'INSTALLED_APPS'. Die App, die den 'CustomUser' enthält, sollte an erster Stelle stehen als die anderen Apps. Ausführliche Erklärung ist hier, https://code.djangoproject.com/ticket/19218 – Babu

0

Ich beginne eine Abhilfe zu denken könnte, um sein - keine Kommentare auf den folgenden in SomeApp/models.py:

from django.contrib.auth.models import User as UserModel 
try: 
    from django.contrib.auth import get_user_model 
except ImportError: #django <= 1.4 doesn't have get_user_model so define our own 
    def get_user_model(): 
     return UserModel 
User = getattr(settings, 'AUTH_USER_MODEL', 'auth.User') 
... 
def SomeModel(models.Model): 
    user = models.ForeignKey(User) # using the name of the model 
    def some_method(self, email): 
     qs = get_user_model().objects.filter(email=email) # using function call to get model class 
+0

Hey @askvictor, wie hast du das am Ende zu lösen? Ich habe das gleiche Problem, aber während der Durchführung von Migrationen und auf einem Paket, das nach meiner App installiert wird. – tzenderman

+0

@tzenderman - löste es durch das Projekt in die Warteschleife setzen, während: -/Für Migrationen ich einige ähnliche Probleme hatte, die ich zusammen mit needed_by oder depends_on durch die Schaffung eines Zwischen Migration gelöst: http: // Stackoverflow.com/questions/17711515/django-süd-zirkuläre-abhängigkeit – askvictor

3

Vergewissern Sie sich Ihr individuelles User-Modell nicht abstrakt ist.

1

Ich denke, das Import von SomeApp einen kreisförmigen Import macht. Deshalb gibt es in docs eine Anweisung, etwas wie ForeignKey mit Calling Settings Attribut zu machen.

Was mich betrifft, ich habe mit dieser Sache begegnet, wenn ich django-Filer-App verwendet. Es gab einen commit auf Github, um Importe mit get_user_model() zu verhindern. Sie können den Code dort als ein Beispiel verwenden, um das Problem zu beheben.

Dieses Problem ist sehr schwierig, denn wenn Sie versuchen, get_user_model() von Shell zu nennen - es funktionieren würde.

8

hatte ich das gleiche Problem gerade jetzt und hier ist meine 2 Cent/Lösung.

Wenn Sie benutzerdefinierte Benutzermodell in models.py verwenden werden Sie für Fremdschlüssel verwenden settings.AUTH_USER_MODEL und für Modell Methoden haben Sie get_user_model() zu verwenden, aber es hat innerhalb die Methode sein. Wegen des zirkulären Imports wird es nicht funktionieren.

from django.conf import settings 
from django.contrib.auth import get_user_model 

class Event(models.Model): 

    recipient = models.ForeignKey(settings.AUTH_USER_MODEL) 
    ... 

    def get_something(self): 

     User = get_user_model() 
     u = User.objects.get(id=...) 
     ... 
+2

Dies ist die definitive Antwort. Danke Freon! –

10

Einfach eins, denke ich. Ich hatte so viele Probleme mit rekursiven Einschlüssen und so weiter ... Nun, die einfachste Sache zu tun, wenn Sie einen ForeignKey hinzufügen, ist es zu schreiben, wie so:

user = models.ForeignKey(settings.AUTH_USER_MODEL, null=False, on_delete=models.CASCADE, verbose_name=_(u"User")) 

Wenn Sie get_user_model verwenden, verwenden Sie es nicht wie Sie. Aufruf

User = get_user_model() 

an der Oberseite des Moduls werden versuchen, Ihr User Modell zu importieren, die in der Tat können nicht „installiert“ wurden. Stattdessen haben Sie mehrere Möglichkeiten:

  • An der Spitze des Moduls, dann

    User = get_user_model # schreiben, müssen Sie Benutzer verwenden() anstelle von Benutzer

  • schreiben get_user_model() überall ist es nützlich. Immer in Methoden oder Funktionen, niemals direkt in einem Modellmodulkörper.

+0

Das hat bei mir funktioniert. Ich importierte get_user_model() am Anfang der Datei. Macht Sinn. Danke – Howie

+0

Wie würden Sie dieses Problem im Deklarationscode behandeln? Eine UserSerializer-Klasse verfügt beispielsweise über eine Meta-Klasse, in der das Modell angegeben ist. Sie können die Definition des Benutzermodells nicht auf Ausführungszeit verschieben, da die gesamte Definition während der Importzeit analysiert wird. – dangonfast

0

Sind Sie mit Süd 0.8.3?

Stellen Sie sicher, dass Sie Süd mindestens 0.8.4

GitHub issue Süd Mitteilung Notes

1
läuft

Die Dokumentation Django hat die Antwort: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#django.contrib.auth.get_user_model

Der relevanteste Abschnitt: Allgemein gesprochen , sollten Sie das Benutzermodell mit der Einstellung AUTH_USER_MODEL in Code referenzieren, der zum Zeitpunkt des Imports ausgeführt wird. get_user_model() funktioniert nur, wenn Django alle Modelle importiert hat.

Die wirkliche Lösung besteht darin, sicherzustellen, dass Sie nur innerhalb einer Methode get_user_model() verwenden, damit es nicht zum Zeitpunkt des Imports ausgeführt wird.