post_save user signal that creates user profile is being called twice causing duplicate key value violates unique constraint, only in admin console

六眼飞鱼酱① 提交于 2019-12-10 19:15:34

问题


I have a model called UserProfile which stores additional data about a django user.

This model has a OneToOneField to django.contrib.auth.models.User

I also have a post save signal on a User object that is fired on initial insert of a User which creates a UserProfile object linked to that User:

def create_user_profile(sender, instance, created, **kwargs):
    if created:
        UserProfile.objects.create(user=instance)

post_save.connect(create_user_profile, sender=User)

User objects can be created via the website front end which when saved creates the UserProfile. This all works fine.

I also have an admin.py file that allows a User and UserProfile object to be created via the admin console:

from django.contrib import admin
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin
from myproject.apps.users.models import UserProfile

admin.site.unregister(User)


class UserProfileInline(admin.StackedInline):
    model = UserProfile
    filter_horizontal = ['companies']
    exclude = [
        'field_1', field_n'
    ]


class UserProfileAdmin(UserAdmin):
    inlines = [UserProfileInline]

admin.site.register(User, UserProfileAdmin)

When creating a new User via the admin console, the UserProfile form is displayed below the User form. If I leave all UserProfile fields as default (i.e. do not enter any data into the form fields or change any default values) the User is created successfully with the UserProfile. If however I attempt to add any values or update any defaults in the UserProfile form it falls over with the error:

IntegrityError at /admin/auth/user/add/

duplicate key value violates unique constraint "users_userprofile_user_id_key"
DETAIL:  Key (user_id)=(6323) already exists.

This indicates the post_save signal on the User object has been called twice, both times the created flag that has been passed into the signal has been set to True resulting in an attempt in inserting a UserProfile object twice with the same User id. Django ends up rolling back the transaction and neither the User or UserProfile objects are inserted.

To add a bizarre twist if I completely remove the post_save signal everything works fine in the admin console and django appears to magically create the UserProfile object for me without even (apparently) knowing about it. Obviously this then breaks the front end as it relies on this post_save signal to create the UserProfile object.

I'm running Django 1.6 using PostgreSQL.

Any shedding of light on this situation would be hugely appreciated. Otherwise I think another approach to how the UserProfile is managed in the admin console will have to be considered.

来源:https://stackoverflow.com/questions/20214362/post-save-user-signal-that-creates-user-profile-is-being-called-twice-causing-du

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!