我正在使用带有postgresql 9.1的Django 1.4.1。
我需要向使用auth应用程序的用户添加配置文件,并允许管理员应用程序创建和编辑此配置文件。 因此,我一直在关注文档部分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'
...
我还激活了django.contrib.auth
中的django.contrib.admin
和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)
现在,当我运行管理员应用并要求添加(创建)新用户时,我被要求通过两步流程创建我的用户:首先,要求提供一个页面只有用户名,密码(两次)和我的两个UserProfile字段。
如果我只键入用户名和密码(两次)并单击“保存”,我会显示该过程的第二页,它允许填写所有其他用户字段以及我的UserProfile字段。有一条消息说“用户”xxxxx“已成功添加。您可以在下面再次编辑它。”,幸运的是我可以编辑两个模型中的字段,它可以工作。
但是,如果我尝试在第一页的一个或两个UserProfile字段中输入任何内容,则提交失败并显示以下消息:
IntegrityError at /admin/auth/user/add/
duplicate key value violates unique constraint "userprofile_userprofile_user_id_key"
DETAIL: Key (user_id)=(7) already exists.
每次尝试都会增加“7”。
如何避免这种行为,或者如何阻止配置文件字段在第一页中可编辑,但是让它们在第二页中进行编辑?
完整追溯:
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.`
答案 0 :(得分:5)
而不是
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
做一个
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.get_or_create(user=instance)
即使是编辑,您也在创建新的用户个人资料对象。
答案 1 :(得分:4)
正如CadentOrange在评论中提到的那样,this answer中描述了这个问题的解决方案。
问题在于使用内联管理表单。这里发生了什么:
User
)post_save
的{{1}}信号处理程序被触发,这会创建一个新的User
对象答案 2 :(得分:2)
create_user_profile
信号和管理表单尝试创建相同的UserProfile。您可以覆盖LocalUserAdmin
以从添加视图中排除UserProfileInline
:
class LocalUserAdmin(UserAdmin):
inlines = (UserProfileInline, )
def get_formsets_with_inlines(self, request, obj=None):
for inline in self.get_inline_instances(request, obj):
# hide MyInline in the add view
if isinstance(inline, UserProfileInline) and obj is None:
continue
yield inline.get_formset(request, obj), inline