我的模特:
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)
但是当我添加新用户并选择一个城市时,我收到了该错误:/ admin / auth / user / add /中的IntegrityError (1062,“密钥'user_id'的重复条目'3'”)
我的代码出了什么问题?如果我没有选择任何城市 - 用户被正确添加。某种程度上,用户被多次添加到UserProfile。
答案 0 :(得分:20)
我最近遇到了同样的问题。当你想到它时,它确实很有意义。在admin中保存带有内联的表单时,它首先保存主模型,然后继续保存每个内联。保存模型时,会触发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进行更新而不是创建。