Django - 管理员中的 UserProfile m2m 字段 - 错误
Posted
技术标签:
【中文标题】Django - 管理员中的 UserProfile m2m 字段 - 错误【英文标题】:Django - UserProfile m2m field in admin - error 【发布时间】:2011-09-01 07:43:30 【问题描述】:我的模型:
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。
【问题讨论】:
【参考方案1】:我最近遇到了同样的问题。当你考虑它时,它实际上是完全有道理的。当您在管理员中保存带有内联的表单时,它首先保存主模型,然后继续保存每个内联。当它保存模型时,你的 post_save 信号被触发并创建一个 UserProfile 来匹配,但现在是时候保存内联了。 UserProfile 内联被认为是新的,因为它以前不存在(没有 pk 值),因此它会尝试另存为全新且不同的 UserProfile,并且您会因违反唯一约束而收到完整性错误。解决方案很简单。只需覆盖UserProfile.save
:
def save(self, *args, **kwargs):
if not self.pk:
try:
p = UserProfile.objects.get(user=self.user)
self.pk = p.pk
except UserProfile.DoesNotExist:
pass
super(UserProfile, self).save(*args, **kwargs)
本质上,这只是检查是否存在相关用户的现有 UserProfile。如果是这样,它将这个 UserProfile 的 pk 设置为那个,以便 Django 进行更新而不是创建。
【讨论】:
谢谢!我有同样的问题。这个解决方案很有意义并且效果很好。 解释得很好。也许应该更新有关存储附加用户数据的 Django 文档以提及这一点,因为文档中提供的示例将无法正常工作。 这也可能表明 post_save 信号由于导入命名问题而被注册了两次。 dispatch_uid="unique-name-goes-here" 也可能解决了这个问题。 UserProfile的save方法在哪里?我正在使用 Django 1.6 。我在这里面临同样的问题。我必须在哪里编写此代码?以上是关于Django - 管理员中的 UserProfile m2m 字段 - 错误的主要内容,如果未能解决你的问题,请参考以下文章