2017-02-23 5 views
0

ich dieses Modell habenDjango: onetoonefield Fehler User-Modell mit Profil erweitern

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

from my_app.models import Teams 

class Profile(models.Model): 
    user = models.OneToOneField(User, on_delete=models.CASCADE) 
    team = models.ForeignKey(Teams, on_delete=models.CASCADE) 

    class Meta: 
     app_label = 'my_app' 

    def __str__(self): 
     return self.name 

@receiver(post_save, sender=User) 
def create_user_profile(sender, instance, created, **kwargs): 
    if created: 
     Profile.objects.create(user=instance) 

@receiver(post_save, sender=User) 
def save_user_profile(sender, instance, **kwargs): 
    instance.profile.save() 

ich dann die Schale gehen in

from django.contrib.auth.models import User 

wenn ich

user = User.objects.create_user(username='test', email='[email protected]', password='test') 

Typ I unsurprisingly bekommen

IntegrityError: NOT NULL constraint failed: my_app_profile.team_id 

aber wenn ich schreibe

user = User.objects.create_user(username='test', email='[email protected]', password='test', team='developer') 

ich

TypeError: 'team' is an invalid keyword argument for this function 

Wenn ich tippe

user = User.objects.create_user(username='test', email='[email protected]', password='test', profile.team='developer') 

ich

SyntaxError: keyword can't be an expression 

Jede Hilfe, Tipps oder Anleitung wäre sehr geschätzt

+0

können Sie Ihre 'User'- und' Team'-Modelle und wie Sie in 'Profile' speichern. – kt14

Antwort

1

Sie haben Team null sein nicht erlaubt, so dass, wenn Sie ein Profil erstellen, etwa so:

@receiver(post_save, sender=User) 
def create_user_profile(sender, instance, created, **kwargs): 
    if created: 
     # Team isn't defined 
     Profile.objects.create(user=instance) 

Sie einen Fehler.

Lassen Team null sein (oder einen Standard im Code oben eingestellt):

class Profile(models.Model): 
    user = models.OneToOneField(User, on_delete=models.CASCADE) 
    team = models.ForeignKey(Teams, on_delete=models.CASCADE, null=True) 

    class Meta: 
     app_label = 'my_app' 

    def __str__(self): 
     return self.name 
+0

Danke @Jens. Gibt es keine Möglichkeit, die Teaminformationen zu den ** kwargs im User.objects.create_user() hinzuzufügen oder bin ich auf diese Methode beschränkt: >>> u = User.objects.get (username = 'fsmith') >>> freds_department = u.employee.department –

+0

Nein - Sie müssen das Benutzerobjekt separat erstellen, bevor Sie ein Profil für den Benutzer erstellen können –

0

Wenn Sie

User.objects.create_user(username='test', email='[email protected]', password='test') 

laufen bekommen Sie IntegrityError wegen post_save Signal. Es versucht, eine Profile Instanz zu erstellen, aber in Profile Modell team kann nicht NULL sein. By default, model fields have null=False.

Wenn Sie

user = User.objects.create_user(username='test', email='[email protected]', 
    password='test', team='developer') 

laufen erhalten Sie Fehler, da team ein Feld in Profile Modell ist, nicht User Modell.

Wenn Sie

user = User.objects.create_user(username='test', email='[email protected]', 
    password='test', profile.team='developer') 

laufen erhalten Sie Fehler, weil Sie nicht . verwenden können Attribute beziehen. Sie müssen __ verwenden, um nach Fremdschlüsseleigenschaften zu filtern. Siehe zum Beispiel this Frage. Aber selbst wenn Sie __ verwenden, gibt es immer noch einen Fehler, da es kein Feld profile in User Modell ist.

Eine weitere Sache, die ich vorschlagen würde, ist, beide post_save Signale in eins zu kombinieren, weil beide denselben Absender haben.

0

Siehe the documentation über ForeignKey.related_name. Standardmäßig hat OneToOneField einen verwandten Namen, um ein Modell einem anderen zuzuordnen, ForeignKey jedoch nicht. Haben Sie einfach diese Option und Sie können user.team zugreifen, um auf das Modell zuzugreifen.

class Profile(models.Model): 
    user = models.OneToOneField(User, on_delete=models.CASCADE) 
    team = models.ForeignKey(Teams, 
          on_delete=models.CASCADE, 
          related_name='team', 
          null=True) 
+0

Er hat keine Probleme beim Zugriff auf die verwandten Objekte, er hat Probleme beim Erstellen eines Profils . –

+0

Meine Schuld schlechtes Lesen. Sie initialisieren Ihr Objekt 'Profile', aber warten Sie einen Wert für' team', fügen Sie 'null = True' hinzu. Und es ist Arbeit, weil Sie Save-Modell mit Nullfeld zulassen. – Buky

Verwandte Themen