Search code examples
djangodjango-modelsdjango-users

how to update fields in userProfile in django


When i try to save data to fields in my UserProfile Django raises an typeerror.

I thought that i extended the UserProfile correctly.

My userProfile model:

class UserProfile(models.Model):
    user = models.OneToOneField(User, unique=True, related_name='profile')
    ....
    initials = models.CharField(max_length=5)

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

In my settings i have added:

AUTH_PROFILE_MODULE = 'timepiece.UserProfile'

When i run a test which should insert values into inherited fields from User, i get an TypeError:

(erp)BAir:website jorrit$ ./manage.py test timepiece.PivotalTest.test_update_users
Creating test database for alias 'default'...
E
======================================================================
ERROR: test_update_users (timepiece.tests.pivotal.PivotalTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/jorrit/virtualenvs/erp/erp/apps/timepiece/tests/pivotal.py", line 73, in test_update_users
    UserProfile.sync_pivotal_users(self.tracker, 450001)
  File "/Users/jorrit/virtualenvs/erp/erp/apps/timepiece/models.py", line 44, in sync_pivotal_users
    initials = m.initials,)
  File "/Library/Python/2.7/site-packages/django/db/models/base.py", line 365, in __init__
    raise TypeError("'%s' is an invalid keyword argument for this function" % kwargs.keys()[0])
TypeError: 'username' is an invalid keyword argument for this function

----------------------------------------------------------------------
Ran 1 test in 1.857s

The function which is tested:

def sync_pivotal_users(tracker, project_id):
    members = tracker.get_memberships_project(project_id)

    for m in members:
    #check if member exist in db
        try:
            #to know if m.id exists in current db
            UserProfile.objects.get(pivotal_member_id=m.id)
            #if not then create a new user
        except UserProfile.DoesNotExist:
            u = UserProfile(pivotal_member_id = m.id,
                            username = m.name, #code breaks here
                            email = m.email, # and here 
                            initials = m.initials,)
            u.save()

Solution

  • The idea behind the approach outlined in the documentation is that when a new User object is created, you attach a handler that in turn creates a UserProfile object:

    The method get_profile() does not create a profile if one does not exist. You need to register a handler for the User model's django.db.models.signals.post_save signal and, in the handler, if created is True, create the associated user profile

    so in your loop through members, you should be creating User objects, not UserProfile objects, as they will automatically be created via the signal.

    It's not really clear how you are getting passwords (the sign up process), but once you have those, you can update the profile for that user using

    profile = current_user_obj.get_profile()
    profile.initial = "some value"
    profile.save()