Frage

Ich habe ein erweitertes Benutzerprofilmodell in Django:

class UserProfile(models.Model):
  user = models.ForeignKey(User, unique=True)
  #other things in that profile

Und ein Signale.py:

from registration.signals import user_registered
from models import UserProfile
from django.contrib.auth.models import User

def createUserProfile(sender, instance, **kwargs):
  profile = users.models.UserProfile()
  profile.setUser(sender)
  profile.save()

user_registered.connect(createUserProfile, sender=User)

Ich stelle sicher, dass das Signal registriert wird, indem Sie dies in meinem haben __init__.py:

import signals

Das sollte mir also ein neues Benutzerprofil für jeden Benutzer erstellen, der sich registriert, oder? Aber es tut es nicht. Ich erhalte immer "userProfile -Matching -Abfrage existiert keine Fehler", wenn ich versuche, mich anzumelden, was bedeutet, dass der Datenbankeintrag nicht vorhanden ist.

Ich sollte sagen, dass ich die Django-Registrierung verwende, die das user_registrierte Signal liefert.

Die Struktur der wichtigen Apps dafür ist, dass ich eine Anwendung namens "Benutzer" habe, dort habe ich: Models.py, signals.py, urls.py und views.py (und einige andere Dinge, die hier keine Rolle spielen sollten ). Die UserProfile -Klasse ist in models.py definiert.

Aktualisieren: Ich habe die Signale geändert.py in:

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

def create_profile(sender, **kw):
    user = kw["instance"]
    if kw["created"]:
        profile = UserProfile()
        profile.user = user
        profile.save()

post_save.connect(create_profile, sender=User)

Aber jetzt bekomme ich einen "IntegrityError":

"Spalten user_id ist nicht eindeutig"

Bearbeiten 2:

Ich habe es gefunden. Sieht so aus, als hätte ich das Signal zweimal registriert. Die Problemumgehung dafür wird hier beschrieben: http://code.djangoproject.com/wiki/signals#helppost_saveseemStookentTwiceforeachsave

Ich musste einen Dispatch_Uid hinzufügen, jetzt sieht meine Signale so aus und wirkt:

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

def create_profile(sender, **kw):
    user = kw["instance"]
    if kw["created"]:
        profile = UserProfile(user=user)
        profile.save()

post_save.connect(create_profile, sender=User, dispatch_uid="users-profilecreation-signal")
War es hilfreich?

Lösung

Sie können es mit post_save im Benutzer implementieren:

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

def create_profile(sender, **kwargs):
    user = kwargs["instance"]
    if kwargs["created"]:
        profile = users.models.UserProfile()
        profile.setUser(sender)
        profile.save()

post_save.connect(create_profile, sender=User)

Bearbeiten:
Eine andere mögliche Lösung, die getestet und funktioniert (ich verwende sie auf meiner Website):

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
def create_profile(sender, **kwargs):
    user = kwargs["instance"]
    if kwargs["created"]:
        up = UserProfile(user=user, stuff=1, thing=2)
        up.save()
post_save.connect(create_profile, sender=User)

Andere Tipps

Sie können das erweiterte Profil erstellen lassen, wenn er stattdessen zuerst für jeden Benutzer zugegriffen wird:

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

class UserProfile(models.Model):
    user = models.ForeignKey(User, unique=True)
    additional_info_field = models.CharField(max_length=50)

User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])

dann benutze

from django.contrib.auth.models import User
user = User.objects.get(pk=1)
user.profile.additional_info_field

Ref: http://www.codekoala.com/blog/2009/quick-django-tip-user-profiles/

Dies hat mir geholfen: primär_key = true

class UserProfile(models.Model):
    user = models.OneToOneField(User, unique=True, primary_key=True, related_name="user")
    phone = models.CharField(('phone'),max_length=30, blank=False, null=True)
    user_building = models.ManyToManyField(Building, blank=True)
    added_by = models.ForeignKey(User, blank=True, null=True, related_name="added")

Wenn du anrufst profile.setUser(), Ich denke du willst passieren instance statt sender als Parameter.

Von dem Dokumentation des user_registered Signal, sender bezieht sich auf User Klasse; instance ist das tatsächliche Benutzerobjekt, das registriert wurde.

Nach meinen neuesten Untersuchungen funktioniert das Erstellen einer separaten Datei, z. B. Singals.py, nicht.

Sie sollten "create_profile" besser mit 'post_save' in deinen Modellen verbinden.

Mein endgültiger Code für Ihre Referenz:

# models.py

# Here goes the definition of class UserProfile.
class UserProfile(models.Model):
    ...

# Use signal to automatically create user profile on user creation.

# Another implementation:
# def create_user_profile(sender, **kwargs):
#     user = kwargs["instance"]
#     if kwargs["created"]:
#         ...
def create_user_profile(sender, instance, created, **kwargs):
    """
    :param sender: Class User.
    :param instance: The user instance.
    """
    if created:
        # Seems the following also works:
        #   UserProfile.objects.create(user=instance)
        # TODO: Which is correct or better?
        profile = UserProfile(user=instance)
        profile.save()

post_save.connect(create_user_profile,
                  sender=User,
                  dispatch_uid="users-profilecreation-signal")

Update für 2018:

Diese Frage hat viele Ansichten gesammelt, vielleicht ist es Zeit für ein Update.

Dies ist die neueste Version für die neueste Django.

from django.dispatch import receiver
from django.db.models.signals import post_save
from django.conf import settings
from models import UserProfile

@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_user_profile(sender, instance=None, created=False, **kwargs):
    if created:
        UserProfile.objects.create(user=instance)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top