2012-12-27 13 views
14

Ich nehme an, dass dies daran liegt, dass mein Superuser von UserProfile abhängig ist, für das noch keine Daten vorhanden sind. Mein Modell sieht aus wieSuper User kann nicht erstellt werden Django

from django.db import models 
from django.contrib.auth.models import User 
from django.db.models.signals import post_save 

class UserProfile(models.Model): 
    user = models.OneToOneField(User) # required 
    location = models.CharField(max_length=100) 
    age = models.PositiveIntegerField(blank=True,null=True) 
    contribution_points = models.PositiveIntegerField() 
    #acheivements = models.ManyToMany() 

def create_user_profile(sender,instance,created,**kwargs): 
    if created: 
     UserProfile.objects.create(user=instance) 

post_save.connect(create_user_profile, sender=User) 

Allerdings habe ich mit dem folgenden Fehler am Ende:

django.db.utils.DatabaseError: (1146, "Table 'savory_db.login_userprofile' doesn't exist") 

trotz syncdb gerade lief zu haben

Hat mein Modell irgendwelche widersprüchliche Felder, die diesen Fehler verursachen würde . Sollte UserProfile nicht auf den Superuser angewendet werden? Wie soll ich das verhindern?

+0

Haben Sie Ihre UserProfile App zu Ihren Einstellungen hinzugefügt? Wenn nicht, wird die Tabelle nicht mit syncdb erstellt. Ihr Code sieht gut aus (zumindest auf den ersten Blick - ich habe eine sehr ähnliche Post-Save-Methode ohne Probleme implementiert). – Colleen

+1

Auch, um klar zu sein, Ihre Aussage "Ich nehme an, dass es daran liegt, dass mein Superuser von UserProfile abhängt" ist inkorrekt - die Abhängigkeit hier geht andersherum. Ich wäre in der Tat überrascht, wenn Ihr createsuperuser-Befehl vollständig fehlgeschlagen wäre - ich wette, es hat den Superuser erstellt und das zugehörige Profil konnte nicht erstellt werden. – Colleen

+0

Wissen Sie auch, dass die Entwickler in Django 1.5 die Anpassung des Django-Benutzermodells erlaubt haben? Wenn Sie stattdessen das Benutzermodell erweitern, müssen Sie kein separates UserProfile erstellen (Sie wissen nicht, ob Sie eigentlich beabsichtigen, dass sie getrennt sind, sondern nur einen Gedanken). – Colleen

Antwort

25

Am 23. März 2011, um 4:25 Uhr, Malcolm Box schrieb:

Further investigation: looks like it's a South/syncdb interaction. The UserProfile will be created by the south migration, but of course that hasn't run when the auth post_install runs to prompt for a superuser.

Sadly syncdb --migrate doesn't do the right thing either.

For now, I'm just creating a superuser manually using ./manage.py shell, but would welcome any ideas on how to solve this better.

Sie den Super-User während syncdb nicht schaffen, werden Sie Benutzerprofiltabelle nicht vorhanden. Sie müssen ein Signal auf Admin erstellen, die ein Benutzerprofil erstellt, das sieht wie es

Das Verfahren Sie wan versagt zu verwenden, um die Datenbank zu initialisieren ist:

python manage.py syncdb --noinput 
python manage.py migrate 
python manage.py createsuperuser 

Referenz: https://groups.google.com/forum/?fromgroups=#!topic/django-users/sBXllxrIdMc

+3

Wenn Sie 'syncdb --all' später ausführen, sollten Tabellen auch für Dinge erstellt werden, die normalerweise über den Süden erstellt werden. Darüber hinaus, wenn Sie einige Dinge mit South und einige mit Syncdb verwalten, wäre das eine hilfreiche Sache in Ihrer ersten Frage zu erwähnen :) – Colleen

0

Ich stieß gerade auf genau dieses Problem - ein Profilmodell, das durch eine Migration erstellt wird, und ein Signalhandler, der bricht, wenn der Superuser mit der ursprünglichen syncdb erstellt wird.

Meine Lösung ist wie folgt.

Zunächst, behandeln Sie den Fall, wo die Tabelle noch nicht existiert. Das ist ein bisschen hässlich und vielleicht zu drastisch (kann andere Fehler maskieren)

@receiver(post_save, sender=User) 
def create_profile(sender, instance, created, **kwargs): 
    try: 
     WheelProfile.objects.get_or_create(user=instance) 
    except DatabaseError: 
     logging.error("Failed to create profile for %s, perhaps migrations haven't run yet?" % instance) 
     from django.db import connection 
     connection._rollback() 

Zweitens einen Handler ausgeführt werden, wenn Migrationen beenden:

from south.signals import post_migrate 

@receiver(post_migrate) 
def create_profiles(app, **kwargs): 
    if app == "wheelcms_axle": 
     for u in User.objects.all(): 
      WheelProfile.objects.get_or_create(user=u) 

Dies wird natürlich auch laufen, wenn künftige Migrationen, die Schaffung Profile für Benutzer, die sie nicht haben. Für mich ist das kein Problem.

Verwandte Themen