【问题标题】:Django multiple user profiles - Display user fields inline in adminDjango 多个用户配置文件 - 在管理员中内联显示用户字段
【发布时间】:2012-09-30 20:24:22
【问题描述】:

我对 Django 比较陌生,我正在尝试实现文档中不太清楚的东西。我的应用程序需要多种类型的用户。因此,我扩展了 django User,创建了一个 Profile 模型,其中包含所有 User 类型中常见的附加字段:

USER_TYPES = (
    ('A', 'UserTypeA'),
    ('B', 'UserTypeB'),
    ('C', 'UserTypeC'),
)

class Profile(models.Model):
    user = models.OneToOneField(User, unique=True)
    about = models.TextField(blank=True)
    user_type = models.CharField(max_length=3, choices=USER_TYPES, default='A')

    def save(self, *args, **kwargs):
        try:
           existing = Profile.objects.get(user=self.user)
           self.id = existing.id #force update instead of insert
        except Profile.DoesNotExist:
           print "Profile not created yet"
        models.Model.save(self, *args, **kwargs) 

def create_user(sender, instance, created, **kwargs):
    print "User Profile Creation: False"
    if created:
        print "User Profile Creation: ", created
        Profile.objects.create(user=instance)

post_save.connect(create_user, sender=Profile)

在settings.py中我设置了:

AUTH_PROFILE_MODULE = 'users.Profile'

之后,我定义了派生自 Profile 模型的 UserTypeX 模型,如下所示:

class UserTypeA(Profile):
    phone_number = models.CharField(max_length=13,blank=False)

class UserTypeB(Profile):
    company_name = models.CharField(max_length=30,blank=False)
    phone_number = models.CharField(max_length=13,blank=False)

    def __init__(self, *args, **kwargs):
        kwargs['user_type'] = 'B'
        super(UserTypeB, self).__init__(*args, **kwargs)

...

我已将这些用户模型注册到管理员,以便我可以独立管理我的用户。

默认管理员行为正确显示所有 Profile 和 UserTypeX 字段,并且由于 Profile 和 User 模型之间的 OneToOneField 关系,User 字段有一个选择框(旁边有一个加号按钮)。所以每当我想创建一个新的 UserTypeX 时,我必须按下加号按钮并填写一个新的弹出窗口,所有默认的 User django 定义的字段。

我现在正在努力做的是显示这些用户字段,而不是在新的弹出窗口中,而是在我的 UserTypeX 添加/编辑页面中内联。我已经阅读了有关 StackedInlines 和 TabularInlines 的文档,但这些文档不适合我的情况,因为我想在祖先的添加/编辑页面中内联父字段,反之亦然。

是否有针对该问题的示例代码(请!)的建议解决方案?提前致谢!


那么,简而言之,有没有办法在管理员的配置文件添加/编辑屏幕中显示用户字段(而不是由于 OneToOneField 关系而选择/添加功能)?


更新:一个相关的问题(虽然没有回答......)简要解决了这个问题:

Reverse Inlines in Django Admin

【问题讨论】:

  • 有什么理由不将Profile 定义为抽象模型?
  • @miki725 不是真的,我只是在尝试在管理员中注册配置文件模型并尝试在其中显示用户字段,看看它是否有效。感谢您的关注!知道我的问题的答案吗?

标签: python django django-models django-admin


【解决方案1】:

不,你不能。但是如果你愿意,你可以让 B 在 A 中内联。或者也许你可以操纵 django 如何在

中显示它

def unicode(自我):

models.py

class A(models.Model):
    name = models.CharField(max_length=50)
    def __unicode__(self):
        return self.name

class B(models.Model):
    name = models.CharField(max_length=50)
    a = models.ForeignKey(A)

admin.py

class B_Inline(admin.TabularInline):  
    model = B
class A_Admin(admin.ModelAdmin):
    inlines = [
        B_Inline,
    ]
admin.site.register(A, A_Admin)
admin.site.register(B)

或者也许您想使用多对多关系?

models.py

class C(models.Model):
    name = models.CharField(max_length=50)
    def __unicode__(self):
        return self.name
class D(models.Model):
    name = models.CharField(max_length=50)
    cs = models.ManyToManyField(C)

admin.py

class C_Inline(admin.TabularInline):  
    model = D.cs.through
class D_Admin(admin.ModelAdmin):
    exclude = ("cs",)
    inlines = [
        C_Inline,
    ]
admin.site.register(C)
admin.site.register(D, D_Admin)

【讨论】:

    【解决方案2】:

    我不知道这是如何工作的 - 你告诉 django 使用 users.Profile 作为你的个人资料模型,但你实际上想使用它的孩子。另外,正如您所说,您想以“错误的方式”使用内联表单。在不了解您到底想要实现什么的情况下,我建议您可以通过定义自定义视图来编辑用户详细信息而不是使用 django admin 来解决内联表单问题。至于不同的配置文件类型 - 我建议在模型中定义一个 profile type 字段,然后根据其值隐藏/显示不同的字段/属性

    【讨论】:

    • 如果我没有错过一些非常重要的东西,我不能在 settings.py 的 AUTH_PROFILE_MODULE 中指定多个配置文件。如果你知道一种方法,我会很高兴知道。内联表单不是一个解决方案,我只是提到它们作为写下我已经尝试过的方法的一种方式。我认为有一种简单的方法可以使用 django admin 实现我想要的,而不必实现一个全新的管理界面,因为我的应用程序中还使用了其他模型,并且在那里它们的管理很容易。
    • 此外,已经考虑了具有配置文件类型字段的想法(配置文件模型中的 user_type 字段)。但我不想让我的所有用户都列在管理员的“个人资料”下。我需要它们是不同的注册模型以便于管理。感谢您的快速回复!
    • 您无需实现全新的管理界面。您仍然可以对大多数模型使用 django 的管理界面 - 但如果您想要对用户/配置文件进行控制,您需要为此编写一个自定义视图。
    • 我目前正在尝试通过扩展默认的 django change_form.html 模板来添加我的自定义模板。我认为通过为我的 UserTypeX 模型定义 ModelForms 并可能使用表单集将所有字段内联,很容易实现默认功能。直到现在都没有成功。我认为要么我遗漏了一些东西,要么有许多额外的变量应该传递给我的自定义模板。您可以推荐任何好的示例实现吗?再次感谢您的努力!
    • 嗯...不是我的头顶 - 每个项目都太不同了...您应该就您的表单集问题提出一个新问题。哦,如果对您有用,请接受我的回答。
    猜你喜欢
    • 1970-01-01
    • 2011-04-13
    • 2023-03-30
    • 2012-07-31
    • 2017-04-26
    • 2012-04-30
    • 1970-01-01
    • 2013-07-03
    • 2011-03-24
    相关资源
    最近更新 更多