内联管理忽略存在实例时的max_num和extra

0 投票
1 回答
1629 浏览
提问于 2025-04-17 03:03

我扩展了标准的Django用户模型,增加了一个用户资料(UserProfile),并建立了用户资料和用户之间的一对一关系,像这样:

class UserProfile(models.Model):
    user = models.OneToOneField(adminmodels.User)
    about = models.TextField('About the author', blank=True)
    picture = models.ImageField('Picture (70px x 70px)', blank=True, upload_to='uploads/profile_pics', default='noone.png')
    user_site = models.URLField(blank=True, verify_exists=False)

class Meta:
    verbose_name = "Profiel"
    verbose_name_plural = "Profielen"

为了在用户管理界面中包含相应的管理员表单,我创建了一个内联管理员表单,并将其添加到用户管理中,像这样:

# Inline admin for the user profile
class UserProfileInline(admin.StackedInline):
    model = UserProfile
    fk_name = 'user'
    max_num = 1
    extra = 0

# Include the extra form
class MyUserAdmin(admin.ModelAdmin):
      inlines = [UserProfileInline, ]

# Re-register the user form
admin.site.unregister(admin.models.User)
admin.site.register(admin.models.User, MyUserAdmin)

最后,为了保存用户资料的实例,我有一个与postsave连接的函数。它看起来像这样:

def on_user_was_saved(sender,instance,created,using,*args,**kwargs):
    if type(instance) == adminmodels.User:    
        if created:
            profile = UserProfile.objects.get_or_create(user = instance)
            profile.save()
        else:
            profile = UserProfile.objects.get_or_create(user = instance)
            profile[0].save()

现在,有两个问题出现了:

  1. 当我在用户资料字段中输入内容并保存用户时,用户和用户资料的实例都被保存了,但用户资料的实例却像是所有字段都是空的一样被保存。虽然在这些字段中输入新内容后可以正常保存,但之前的情况就不行。
  2. 出现了第二个用户资料表单实例;max_num设置被忽略了。

在benjaoming的建议后,我将post_save回调函数改成了:

    try:
        profile = UserProfile.objects.get(user = instance)
        profile.save()
    except:
        profile = UserProfile.objects.get_or_create(user = instance)
        profile[0].save()

然而,这并没有解决我之前遇到的任何问题。

1 个回答

1

这里主要的问题是,你并没有真正处理用户资料表单。看看你写的代码:在任何时候,你都没有把用户资料中输入的值保存到数据库里。

另外,admin.StackedInline并不是为了你想要的功能而设计的。它是用来管理一对多的关系,而不是一对一的关系。

如果你一定要在管理后台实现你所描述的功能,最好的办法是给AdminSite添加一个自定义视图,里面包含添加和编辑用户的表单。或者,让用户填写两个表单来创建一个用户。

总之,你可以了解更多关于AdminSite中添加视图的内容。

撰写回答