Django - 管理中的 UserProfile m2m 字段 - 错误
我的模型:
class UserProfile(models.Model):
TYPES_CHOICES = (
(0, _(u'teacher')),
(1, _(u'student')),
)
user = models.ForeignKey(User, unique=True)
type = models.SmallIntegerField(default=0, choices=TYPES_CHOICES, db_index=True)
cities = models.ManyToManyField(City)
class City(models.Model):
name = models.CharField(max_length=50)
slug = models.SlugField(max_length=50)
在 admin.py 中:
admin.site.unregister(User)
class UserProfileInline(admin.StackedInline):
model = UserProfile
class UserProfileAdmin(UserAdmin):
inlines = [UserProfileInline]
admin.site.register(User, UserProfileAdmin)
@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
"""Create a matching profile whenever a user object is created."""
if created:
profile, new = UserProfile.objects.get_or_create(user=instance)
但是当我添加新用户并选择一个城市时,我收到该错误: IntegrityError at /admin/auth/user/add/ (1062,“密钥‘user_id’的重复条目‘3’”)
我的代码有什么问题?如果我不选择任何城市 - 用户将被正确添加。以某种方式,用户被多次添加到 UserProfile 中。
My models:
class UserProfile(models.Model):
TYPES_CHOICES = (
(0, _(u'teacher')),
(1, _(u'student')),
)
user = models.ForeignKey(User, unique=True)
type = models.SmallIntegerField(default=0, choices=TYPES_CHOICES, db_index=True)
cities = models.ManyToManyField(City)
class City(models.Model):
name = models.CharField(max_length=50)
slug = models.SlugField(max_length=50)
In admin.py:
admin.site.unregister(User)
class UserProfileInline(admin.StackedInline):
model = UserProfile
class UserProfileAdmin(UserAdmin):
inlines = [UserProfileInline]
admin.site.register(User, UserProfileAdmin)
@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
"""Create a matching profile whenever a user object is created."""
if created:
profile, new = UserProfile.objects.get_or_create(user=instance)
But when I add new user and select a city I get that error: IntegrityError at /admin/auth/user/add/
(1062, "Duplicate entry '3' for key 'user_id'")
What is wrong with my code? If I don't select any city - user is added properly. Some way, user is being added to UserProfile more than once.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我最近也遇到了同样的问题。当你仔细思考时,它实际上是非常有道理的。当您在管理中保存带有内联的表单时,它首先保存主模型,然后继续保存每个内联。当它保存模型时,您的 post_save 信号将被触发,并创建一个 UserProfile 来匹配,但现在是时候保存内联了。 UserProfile 内联被认为是新的,因为它以前不存在(没有 pk 值),因此它尝试另存为全新且不同的 UserProfile,并且您会因违反唯一约束而收到完整性错误。解决方案很简单。只需覆盖
UserProfile.save
:本质上,这只是检查相关用户是否存在现有的 UserProfile。如果是这样,它将将此 UserProfile 的 pk 设置为该 UserProfile 的 pk,以便 Django 执行更新而不是创建。
I had this same issue recently. It actually makes perfect sense when you think about it. When you save a form with inlines in the admin, it saves the main model first, and then proceeds to save each inline. When it saves the model, your post_save signal is fired off and a UserProfile is created to match, but now it's time to save the inlines. The UserProfile inline is considered new, because it didn't exist previously (has no pk value), so it tries to save as an entirely new and different UserProfile and you get that integrity error for violating the unique constraint. The solution is simple. Just override
UserProfile.save
:Essentially, this just checks if there's an existing UserProfile for the user in question. If so, it sets this UserProfile's pk to that one's so that Django does an update instead of a create.