2009-12-15 12 views
44

मैं 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 मिलान क्वेरी मौजूद नहीं है" त्रुटियां मिलती हैं, जिसका अर्थ है कि डेटाबेस प्रविष्टि नहीं है।

मुझे कहना चाहिए कि मैं django-पंजीकरण का उपयोग करता हूं, जो उपयोगकर्ता_registered सिग्नल प्रदान करता है।

इसके लिए महत्वपूर्ण ऐप्स की संरचना यह है कि मेरे पास "उपयोगकर्ता" नामक एक एप्लिकेशन है, मेरे पास है: 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:

मुझे यह मिला। ऐसा लगता है कि मैंने सिग्नल को दो बार पंजीकृत किया था। इस के लिए वैकल्पिक हल यहाँ वर्णित है: 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") 
+0

आप संरचना अपने Django ऐप्लिकेशन पोस्ट किया जा सका। मैं आपके कोड में कुछ पंक्तियों के बारे में उत्सुक हूं जैसे 'प्रोफ़ाइल = user.models.UserProfile()' - क्या आपके पास 'उपयोगकर्ता' नामक मॉड्यूल है? UserProfile() कहां स्थित है। – czarchaic

+0

यह उपयोगकर्ता है, मुझे नहीं पता कि उस टाइपो में कैसे मिला, लेकिन समस्या एक जैसी है। मुझे आश्चर्य है कि क्यों पाइथन ने गलत वर्तनी पथ के लिए कोई त्रुटि नहीं डाली। – Kai

+0

इस समाधान के लिए धन्यवाद, मैं django के साथ नया हूँ, और मैं नहीं जानता कि कैसे उपयोगकर्ता प्रोफ़ाइल के बारे में दूसरों को डेटा बचाता है। मुझे लगता है कि आप उपयोगकर्ता को उपयोगकर्ता प्रोफाइल में मॉडल को सहेजते हैं, लेकिन रजिस्टर फॉर्म से अन्य डेटा (आपके signals.py का उपयोग करके) कितना बीमार है? थांस्क (अंग्रेजी के साथ खेद है) – Asinox

उत्तर

27

आप उपयोगकर्ता पर 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) 
+1

"profile.setUser (उपयोगकर्ता)" होना चाहिए, मुझे लगता है। लेकिन फिर मुझे "कॉलम user_id अद्वितीय नहीं है" मिलता है। उस पर कोई विचार? – Kai

+0

मैंने अपने उत्तर के लिए एक और संभावित समाधान जोड़ा, इसे देखें। – Agos

+0

मुझे "कॉलम user_id अद्वितीय नहीं है", क्या आप मुझे अपना UserProfile मॉडल दिखा सकते हैं? शायद मुझे विदेशीकी() गलत के साथ कुछ मिला। – Kai

5

जब आप profile.setUser() कहते हैं, मुझे लगता है कि आप पास करना चाहते हैं पैरामीटर के रूप में sender के बजाय instance

documentation of the user_registered signal से senderUser वर्ग को संदर्भित करता है; instance वास्तविक उपयोगकर्ता ऑब्जेक्ट है जो पंजीकृत था।

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/

6

यह मैं मदद की: primary_key = सच

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") 
+2

में पास करने की आवश्यकता नहीं होगी primary_key = True का अर्थ शून्य = गलत और अद्वितीय = सही है। https://docs.djangoproject.com/en/dev/ref/models/fields/ – flyingfoxlee

1
मेरी नवीनतम शोध के अनुसार

, एक अलग फाइल बनाने, जैसे, singals.py , काम नहीं करता।

आप अपने model.py में सीधे 'create_profile' को '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") 
संबंधित मुद्दे