1

我对 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 关系而选择/添加功能)?


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

Django Admin中的反向内联

4

2 回答 2

1

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

def unicode(自我):

模型.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)

管理员.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)

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

模型.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)

管理员.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)
于 2017-11-01T09:46:34.773 回答
0

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

于 2012-10-10T11:33:03.730 回答