简体   繁体   中英

How to get a list of CharField for one model field that it is possible to increase with a “+” button to add other fields in Django admin?

Here is some fields I have on the admin page of the User model I extended:

一些用户字段

But the fact is I don't want textAreaFields for soins and historique fields, I would prefer it look like a list in which it would be possible to add other fields:

像这个例子

But I don't know how to do that, I checked the inlines models which very looks like the result I wish for but I did not manage to integrate it into my model.

I also checked the ArrayField (I have a postgre DB) but I don't find an easy way to add fields from the admin page like the second picture.

Here is my 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)

and here is my 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',)

The perfect solution would be to integrate the inline models into mine but I don't get how to do it, is it possible?

All I have achieved is to create the list I want only in an other model by using the Django doc .

Edit:

I follow the @carlosleite advice, and I get this: image

We're close but it's isn't exactly what I want: That the list is beside the "soins" field.

I try this, I think it what I want to do but I have the following error:

<class 'users.admin.SoinsInline'>: (admin.E202) 'users.User' has no ForeignKey to 'users.User'.

Here is my new 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)

And my new 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)

Make a model for "soins" (actually - Soins) Ma ke a relation with User (onetomany)

ant then use inline edition on admin.


Returns the number of extra inline forms to use. By default, returns the InlineModelAdmin.extra attribute.

Override this method to programmatically determine the number of extra inline forms. For example, this may be based on the model instance (passed as the keyword argument 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM