46

djangoに拡張UserProfileモデルがあります:

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

そしてsignals.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)

私はこれを私の中に持っていることによって信号が登録されることを確認します__init__.py

import signals

これで、登録するすべてのユーザーに対して新しいUserProfileが作成されますね。しかし、そうではありません。ログインしようとすると、常に「UserProfile一致するクエリが存在しません」というエラーが表示されます。これは、データベースエントリが存在しないことを意味します。

user_registeredシグナルを提供するdjango-registrationを使用していると言えます。

このための重要なアプリの構造は、「users」と呼ばれる1つのアプリケーションがあり、models.py、signals.py、urls.py、views.py(およびここでは重要ではない他のいくつかのもの)があります。 )。UserProfileクラスはmodels.pyで定義されています。

更新:signals.pyを次のように変更しました:

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)

しかし今、私は「IntegrityError」を受け取ります:

「列user_idは一意ではありません」

編集2:

見つけた。どういうわけか私は信号を2回登録したようです。これの回避策はここで説明されています:http://code.djangoproject.com/wiki/Signals#Helppost_saveseemstobeemittedtwiceforeachsave

dispatch_uidを追加する必要がありましたが、signals.pyは次のようになり、機能しています。

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")
4

6 に答える 6

31

ユーザーにpost_saveを使用して実装できます。

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)

編集:
テストされて機能する別の可能な解決策(私は自分のサイトでそれを使用しています):

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)
于 2009-12-15T23:02:30.670 に答える
6

これは私を助けました:primary_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")
于 2012-03-28T13:26:01.853 に答える
6

代わりに、ユーザーごとに最初にアクセスしたときに作成される拡張プロファイルを取得できます。

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])

次に使用します

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

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

于 2011-05-01T23:00:44.750 に答える
5

を呼び出すときは、パラメータとしてではなく、profile.setUser()渡したいと思います。instancesender

user_registeredシグナルのドキュメントから、クラスをsender参照します。登録された実際のユーザーオブジェクトです。Userinstance

于 2009-12-15T22:54:15.413 に答える
1

私の最新の調査によると、singals.pyなどの別のファイルを作成しても機能しません。

「create_profile」をmodels.pyの「post_save」に直接接続することをお勧めします。そうしないと、このコードは別のファイルにあり、誰もインポートしないため、実行されません。

あなたの参照のための私の最終的なコード:

# 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")
于 2017-07-19T01:48:11.823 に答える
0

2018年の更新:

この質問は多くの意見を集めました、多分それは更新の時間です。

これは最新の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)
于 2018-03-30T04:02:38.530 に答える