Opened 10 months ago

Closed 9 months ago

Last modified 9 months ago

#33547 closed Bug (fixed)

Admin TabularInline with readonly field fail to render on validation error

Reported by: David Glenck Owned by: Mariusz Felisiak
Component: contrib.admin Version: 4.0
Severity: Release blocker Keywords: tabularinline readonly
Cc: Antoine Humbert Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Error Message "'dict' object has no attribute 'is_hidden'"
In this line https://github.com/django/django/blob/e0442a628eb480eac6a7888aed5a86f83499e299/django/contrib/admin/templatetags/admin_modify.py#L141
Here in the template https://github.com/django/django/blob/e0442a628eb480eac6a7888aed5a86f83499e299/django/contrib/admin/templates/admin/edit_inline/tabular.html#L28

In my case the reasong is that the field in the inline is readonly which makes it a dict without the "is_hidden" attribute.

Code to reproduce.
Model:

class MyModel(models.Model):
    other_model = models.ForeignKey('OtherModel', on_delete=models.CASCADE)

    def clean(self):
        raise ValidationError()

Inline:

class MyModelInline(admin.TabularInline):
    model = MyModel
    readonly_fields = ['my_readonly_field']

    @admin.display(description='MyReadonlyField')
    def my_readonly_field(self, instance):
        return 'value'

Then using this tabular inline in OtherModelAdmin.
Trying to add a new MyModel in OtherModel via admin will raise the ValidationError and consequently cause this issue.

Changing this line https://github.com/django/django/blob/e0442a628eb480eac6a7888aed5a86f83499e299/django/contrib/admin/templatetags/admin_modify.py#L141 to:

if not getattr(field.field, 'is_hidden', False):

Seems to fix the issue.

Change History (7)

comment:1 in reply to:  description Changed 10 months ago by Mariusz Felisiak

Cc: Antoine Humbert added
Severity: NormalRelease blocker
Triage Stage: UnreviewedAccepted

Thanks for the report.

Changing this line https://github.com/django/django/blob/e0442a628eb480eac6a7888aed5a86f83499e299/django/contrib/admin/templatetags/admin_modify.py#L141 to:

if not getattr(field.field, 'is_hidden', False):

Seems to fix the issue

field dictionary for AdminReadonlyField has the is_hidden key so we should use it instead of assuming it's False.

Regression in de95c826673be9ea519acc86fd898631d1a11356.
Reproduces at e0442a628eb480eac6a7888aed5a86f83499e299.

comment:2 Changed 10 months ago by Mariusz Felisiak

Owner: changed from nobody to Mariusz Felisiak
Status: newassigned

comment:3 Changed 10 months ago by Mariusz Felisiak

Has patch: set

comment:4 Changed 9 months ago by Carlton Gibson

Triage Stage: AcceptedReady for checkin

comment:5 Changed 9 months ago by GitHub <noreply@…>

Resolution: fixed
Status: assignedclosed

In 445b075d:

Fixed #33547 -- Fixed error when rendering invalid inlines with readonly fields in admin.

Regression in de95c826673be9ea519acc86fd898631d1a11356.

Thanks David Glenck for the report.

comment:6 Changed 9 months ago by Mariusz Felisiak <felisiak.mariusz@…>

In 82f25266:

[4.0.x] Fixed #33547 -- Fixed error when rendering invalid inlines with readonly fields in admin.

Regression in de95c826673be9ea519acc86fd898631d1a11356.

Thanks David Glenck for the report.
Backport of 445b075def2c037b971518963b70ce13df5e88a2 from main

comment:7 Changed 9 months ago by Antoine Humbert

May be a bit late now, but I think the original reason for this kind of bug is because of API inconsistency between AdminReadonlyField and AdminField where .field attribute is a dict (with keys) for the former and a BoundField (with attributes) for the latter.
The difference works as soon as it is used in templates because object attributes and dict keys are accessed using the same syntax. But as soon as it is used in python code (like in reported bug), it breaks. Making .field a namedtuple or a dataclass in AdminReadonlyField would have solve the problem (without hurting usage in templates) without requiring some exceptions management, and would also make things easier to manage if .field is used somewhere else in python code.

What do you think about this ?

Note: See TracTickets for help on using tickets.
Back to Top