Django多个用户配置文件 - 在admin中内联显示用户字段

时间:2012-10-10 11:19:29

标签: python django django-models django-admin

我对Django相对较新,我正在努力实现文档中不太清楚的东西。我的应用程序需要多种类型的用户。因此,我扩展了django用户,创建了一个包含所有用户类型中常见的其他字段的配置文件模型:

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字段,并且User字段旁边有一个选择框(旁边有加号) - 由于Profile和User模型之间的OneToOneField关系。因此,每当我想要创建一个新的UserTypeX时,我必须按加号按钮并在所有默认的用户django定义的字段中填入一个新的弹出窗口。

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

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


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


更新:简要解决问题的相关问题(虽然没有答案......):

Reverse Inlines in Django Admin

2 个答案:

答案 0 :(得分:1)

不,你不能。但是如果你愿意的话,你可以在A中内嵌B。或者也许你可以操纵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)

答案 1 :(得分:0)

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