首页 > 解决方案 > 如何获取一个模型字段的 CharField 列表,可以使用“+”按钮增加以在 Django admin 中添加其他字段?

问题描述

这是我扩展的用户模型的管理页面上的一些字段:

一些用户字段

但事实是我不希望 textAreaFields 用于 soinshistorique字段,我希望它看起来像一个可以添加其他字段的列表:

像这个例子

但我不知道该怎么做,我检查了内联模型,它看起来很像我想要的结果,但我没有设法将它集成到我的模型中。

我还检查了ArrayField(我有一个 postgre 数据库),但我没有找到像第二张图片那样从管理页面添加字段的简单方法。

这是我的model.py

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(max_length=254, unique=True)
    name = models.CharField(max_length=254, null=True, blank=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    last_login = models.DateTimeField(null=True, blank=True)
    date_joined = models.DateTimeField(auto_now_add=True)
    story = models.TextField(blank=True)
    forename = models.CharField(max_length=254, null=True, blank=True)
    historique = models.TextField(blank=True)
    adress1 = models.CharField(max_length=254, null=True, blank=True)
    adress2 = models.CharField(max_length=254, null=True, blank=True)
    dateNaiss = models.DateField(null=True, blank=True)
    fidelity = models.IntegerField(null=True, blank=True, editable=True)
    phone = models.CharField(max_length=16, null=True, blank=True)
    soins = models.TextField(blank=True)

    USERNAME_FIELD = 'email'
    EMAIL_FIELD = 'email'
    REQUIRED_FIELDS = ['name', 'forename', 'adress1', 'adress2', 'dateNaiss', 'phone']

    objects = UserManager()

    def get_absolute_url(self):
        return "/users/%i/" % (self.pk)

这是我的admin.py

class UserAdmin(BaseUserAdmin):
    fieldsets = (
        (None, {'fields': ('email', 'name', 'last_login', 'phone', 'adress1', 'adress2')}),
        ('Infos Personnelles', {'fields': (
            'story',
            'historique',
            'soins',
            'fidelity',
        )}),
    )
    add_fieldsets = (
        (
            None,
            {
                'classes': ('wide',),
                'fields': ('email', 'password1', 'password2')
            }
        ),
    )

    list_display = ('is_staff', 'email', 'name', 'forename', 'adress1', 'adress2', 'dateNaiss', 'last_login')
    list_filter = ('is_superuser', 'forename')
    search_fields = ('email',)
    ordering = ('email',)
    filter_horizontal = ('groups', 'user_permissions',)

完美的解决方案是将内联模型集成到我的中,但我不知道该怎么做,这可能吗?

我所做的只是通过使用Django doc在其他模型中创建我想要的列表。

编辑 :

我遵循@carlosleite 的建议,我得到了这个:图片

我们已经很接近了,但这并不是我想要的:该列表位于“soins”字段旁边。

我试试这个,我认为这是我想做的,但我有以下错误:

<class 'users.admin.SoinsInline'>: (admin.E202) 'users.User' 没有到 'users.User' 的外键。

这是我的新models.py

class SoinsList(models.Model):
    soin = models.CharField(blank=True, max_length=255)

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(max_length=254, unique=True)
    name = models.CharField(max_length=254, null=True, blank=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    last_login = models.DateTimeField(null=True, blank=True)
    date_joined = models.DateTimeField(auto_now_add=True)
    story = models.TextField(blank=True)
    forename = models.CharField(max_length=254, null=True, blank=True)
    historique = models.TextField(blank=True)
    adress1 = models.CharField(max_length=254, null=True, blank=True)
    adress2 = models.CharField(max_length=254, null=True, blank=True)
    dateNaiss = models.DateField(null=True, blank=True)
    fidelity = models.IntegerField(null=True, blank=True, editable=True)
    phone = models.CharField(max_length=16, null=True, blank=True)
    soins = models.ForeignKey(SoinsList, on_delete=models.CASCADE)

    USERNAME_FIELD = 'email'
    EMAIL_FIELD = 'email'
    REQUIRED_FIELDS = ['name', 'forename', 'adress1', 'adress2', 'dateNaiss', 'phone']

    objects = UserManager()

    def get_absolute_url(self):
        return "/users/%i/" % (self.pk)

还有我的新admin.py

class SoinsInline(admin.TabularInline):
    model = User

class UserAdmin(BaseUserAdmin):
    fieldsets = (
        (None, {'fields': ('email', 'name', 'last_login', 'phone', 'adress1', 'adress2')}),
        ('Infos Personnelles', {'fields': (
            'story',
            'historique',
            'soins',
            'fidelity',
        )}),
    )
    add_fieldsets = (
        (
            None,
            {
                'classes': ('wide',),
                'fields': ('email', 'password1', 'password2')
            }
        ),
    )
    inlines = [
        SoinsInline,
    ]
    list_display = ('is_staff', 'email', 'name', 'forename', 'adress1', 'adress2', 'dateNaiss', 'last_login')
    list_filter = ('is_superuser', 'forename')
    search_fields = ('email',)
    ordering = ('email',)
    filter_horizontal = ('groups', 'user_permissions',)


admin.site.register(User, UserAdmin)

标签: pythondjangodjango-admin

解决方案


为“soins”制作模型(实际上是 - Soins)与 User 建立关系(onetomany)

ant 然后在管理员上使用内联版本。


返回要使用的额外内联表单的数量。默认情况下,返回 InlineModelAdmin.extra 属性。

重写此方法以编程方式确定额外内联表单的数量。例如,这可能基于模型实例(作为关键字参数 obj 传递):

#sample from the docs
class BinaryTreeAdmin(admin.TabularInline):
    model = BinaryTree

    def get_extra(self, request, obj=None, **kwargs):
        extra = 2  # number of extra "forms"   <<<<<<<
        if obj:
            return extra - obj.binarytree_set.count()
        return extra

推荐阅读