【问题标题】:Django - UserProfile m2m field in admin - errorDjango - 管理员中的 UserProfile m2m 字段 - 错误
【发布时间】: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。

【问题讨论】:

    标签: django django-models django-admin django-users


    【解决方案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 。我在这里面临同样的问题。我必须在哪里编写此代码?
    猜你喜欢
    • 1970-01-01
    • 2019-09-18
    • 1970-01-01
    • 2016-08-26
    • 2015-06-09
    • 2012-09-19
    • 2014-04-21
    • 2012-06-05
    • 2011-05-19
    相关资源
    最近更新 更多