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

查看:230
本文介绍了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(发件人,实例,创建,** kwargs):
每当用户对象创建一个匹配的配置文件$
如果创建的话:
profile,new = UserProfile.objects.get_or_create(user = instance)

但是当我添加新用户并选择一个城市时,我会收到以下错误:IntegrityError at / admin / auth / user / add /
(1062,重复条目3 'user_id')



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

解决方案

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

  def save(self,* args ,** kwargs):
如果不是self.pk:
try:
p = UserProfile.objects.get(user = self.user)
self.pk = p.pk
除了UserProfile.DoesNotExist:
pass

super(UserProfile,self).save(* args,** kwargs)
/ pre>

本质上,这只是检查是否有一个现有的UserProfile用于有问题的用户。如果是这样,它将该UserProfile的pk设置为那个,以便Django进行更新,而不是创建。


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.

解决方案

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)

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天全站免登陆