Django - 管理员中的 UserProfile m2m 字段 - 错误 [英] Django - UserProfile m2m field in admin - error

查看:17
本文介绍了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 中:

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)

但是当我添加新用户并选择一个城市时,我得到了那个错误:IntegrityError at/admin/auth/user/add/(1062,密钥user_id"的重复条目3"")

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'")

我的代码有什么问题?如果我不选择任何城市 - 用户已正确添加.以某种方式,用户被多次添加到 UserProfile.

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.

推荐答案

我最近也遇到了同样的问题.当你考虑它时,它实际上是完全有道理的.当您在管理员中保存带有内联的表单时,它首先保存主模型,然后继续保存每个内联.当它保存模型时,你的 post_save 信号被触发并创建一个 UserProfile 来匹配,但现在是时候保存内联了.UserProfile 内联被认为是新的,因为它以前不存在(没有 pk 值),因此它会尝试另存为全新且不同的 UserProfile,并且您会因违反唯一约束而收到完整性错误.解决方案很简单.只需覆盖 UserProfile.save:

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:

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 进行更新而不是创建.

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.

这篇关于Django - 管理员中的 UserProfile m2m 字段 - 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆