I'm using Django 1.4.1 with postgresql 9.1.
I need to add a profile to the User given with the auth app, and to allow the admin app to create and edit this profile. Thus I've been following the docs section Storing additional information about users :
class UserProfile(models.Model):
user = models.OneToOneField(User)
bio = models.TextField(null = True, blank = True)
contact = models.TextField(null = True, blank = True)
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
...
AUTH_PROFILE_MODULE = 'userprofile.UserProfile'
...
I also activated the django.contrib.auth
and django.contrib.admin
apps in INSTALLED_APPS
.
class UserProfileInline(admin.StackedInline):
model = UserProfile
can_delete = False
verbose_name_plural = 'profile'
class UserAdmin(UserAdmin):
inlines = (UserProfileInline, )
# Re-register UserAdmin
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
Now, when I run the admin app and ask to add (create) a new user, I'm asked to create my user through a two-step process : first, a page asking for only the username, password (twice), and my two UserProfile fields.
If I type only the username and the password (twice) and click "Save", I'm showed the second page of the process, which allows to fill in all the other User fields, as well as my UserProfile fields. There's a message saying "The user "xxxxx" was added successfully. You may edit it again below.", and fortunately I can edit fields from both models, it works.
But if I try to type anything into one or both of my UserProfile fields in the first page, the submit fails with the message :
IntegrityError at /admin/auth/user/add/
duplicate key value violates unique constraint "userprofile_userprofile_user_id_key"
DETAIL: Key (user_id)=(7) already exists.
The "7" is incremented each time I try.
How can that behavior be avoided, or alternatively how can I prevent the profile fields to be editable in the first page, but letting them be edited in the second page ?
Full traceback :
Environment: Request Method: POST Request URL: http://127.0.0.1:8000/admin/auth/user/add/ Django Version: 1.4.1 Python Version: 2.7.3 Installed Applications: ('django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.admin', 'django.contrib.admindocs', 'userprofile') Installed Middleware: ('django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware') Traceback: File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response 111. response = callback(request, *callback_args, **callback_kwargs) File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in wrapper 366. return self.admin_site.admin_view(view)(*args, **kwargs) File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapped_view 91. response = view_func(request, *args, **kwargs) File "/usr/local/lib/python2.7/dist-packages/django/views/decorators/cache.py" in _wrapped_view_func 89. response = view_func(request, *args, **kwargs) File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/sites.py" in inner 196. return view(request, *args, **kwargs) File "/usr/local/lib/python2.7/dist-packages/django/views/decorators/debug.py" in sensitive_post_parameters_wrapper 69. return view(request, *args, **kwargs) File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapper 25. return bound_func(*args, **kwargs) File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapped_view 91. response = view_func(request, *args, **kwargs) File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in bound_func 21. return func(self, *args2, **kwargs2) File "/usr/local/lib/python2.7/dist-packages/django/db/transaction.py" in inner 209. return func(*args, **kwargs) File "/usr/local/lib/python2.7/dist-packages/django/contrib/auth/admin.py" in add_view 114. extra_context) File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapper 25. return bound_func(*args, **kwargs) File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapped_view 91. response = view_func(request, *args, **kwargs) File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in bound_func 21. return func(self, *args2, **kwargs2) File "/usr/local/lib/python2.7/dist-packages/django/db/transaction.py" in inner 209. return func(*args, **kwargs) File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in add_view 956. self.save_related(request, form, formsets, False) File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in save_related 733. self.save_formset(request, form, formset, change=change) File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in save_formset 721. formset.save() File "/usr/local/lib/python2.7/dist-packages/django/forms/models.py" in save 497. return self.save_existing_objects(commit) + self.save_new_objects(commit) File "/usr/local/lib/python2.7/dist-packages/django/forms/models.py" in save_new_objects 628. self.new_objects.append(self.save_new(form, commit=commit)) File "/usr/local/lib/python2.7/dist-packages/django/forms/models.py" in save_new 731. obj.save() File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py" in save 463. self.save_base(using=using, force_insert=force_insert, force_update=force_update) File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py" in save_base 551. result = manager._insert([self], fields=fields, return_id=update_pk, using=using, raw=raw) File "/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py" in _insert 203. return insert_query(self.model, objs, fields, **kwargs) File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py" in insert_query 1576. return query.get_compiler(using=using).execute_sql(return_id) File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/compiler.py" in execute_sql 910. cursor.execute(sql, params) File "/usr/local/lib/python2.7/dist-packages/django/db/backends/util.py" in execute 40. return self.cursor.execute(sql, params) File "/usr/local/lib/python2.7/dist-packages/django/db/backends/postgresql_psycopg2/base.py" in execute 52. return self.cursor.execute(query, args) Exception Type: IntegrityError at /admin/auth/user/add/ Exception Value: duplicate key value violates unique constraint "userprofile_userprofile_user_id_key" DETAIL: Key (user_id)=(7) already exists.`
As CadentOrange mentioned in a comment, the solution to this problem is described in this answer.
The problem is with using an inline admin form. Here's what happens:
User
)post_save
signal handler for User
is fired, which creates a new UserProfile
objectUserProfile
, resulting in the dupe).If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With