Felipe Hogrefe Bento
Felipe Hogrefe Bento

Reputation: 297

Django Admin: field not listed in list_display being displayed

My project consists in items to be processed and then classified, so I have two main models: Item and Classification, as follows:

class Item(models.Model):
    seq_prod = models.IntegerField(primary_key=True)
    value = models.DecimalField(decimal_places=4, max_digits=20)

class Classification(models.Model):
    item = models.ForeignKey(Item, db_index=True, on_delete=models.CASCADE)    
    rule = models.ForeignKey(Rule, null=True, blank=True, on_delete=models.CASCADE)
    atribute = models.ForeignKey(Atribute, on_delete=models.CASCADE)
    valid_clas = models.BooleanField(default=True)
    dat_emission = models.DateField()

Models Rule and Atribute doesn't really matter for the problem.

As for the admin part we have:

class ClassificationInline(admin.TabularInline):
    model = Classification
    list_display = ('rule', 'atribute', 'valid_clas')

@admin.register(Item)
class ItemAdmin(admin.ModelAdmin):
    list_display = ('desc', 'value',)

    inlines = [
        ClassificationInline,
    ]

Notice that in Classification model I haven't specified a primary key field, so Django creates an id column.

In the list_display at ClassificationInline we have only 'rule', 'atribute' and 'valid_clas', notice that neither 'id' nor 'dat_emission' are present. However, in the interface Django shows a 'dat_emission' column and doesn't show 'id' column.

Shouldn't only fields specified at the list_display be displayed? How can I remove 'dat_emission'?

Upvotes: 1

Views: 1093

Answers (2)

Felipe Hogrefe Bento
Felipe Hogrefe Bento

Reputation: 297

As @weAreStarDust posted list_display doesn't work for Inlines, so I need to add dat_emission to the exclude. And besides that the following code was needed:

def get_readonly_fields(self, request, obj=None):
    result = list(set(
        [field.name for field in self.opts.local_fields] +
        [field.name for field in self.opts.local_many_to_many]
    ))
    result.remove('id')
    result.remove('dat_emission')
    return result

The final code for the Inline is:

class ClassificationInline(admin.TabularInline):
    model = Classification
    exclude = ('dat_emission', )
    ordering = ('rule',)

    can_delete = False

    def has_add_permission(self, request):
        return False

    def get_readonly_fields(self, request, obj=None):
        result = list(set(
            [field.name for field in self.opts.local_fields] +
            [field.name for field in self.opts.local_many_to_many]
        ))
        result.remove('id')
        result.remove('dat_emissao')
        return result

Upvotes: 0

weAreStarsDust
weAreStarsDust

Reputation: 2752

Use exclude in your Inline class

class ClassificationInline(admin.TabularInline):
    model = Classification
    exclude = ('valid_clas', 'dat_emission', )

As i see in django source code, there is no list_display property for TabularInline class, сorrect me if I'm wrong.

Upvotes: 2

Related Questions