I have a tabular inline model in the Django admin. I need 1 of the fields to not be changeable after it has been created, but setting it as readonly (via readonly_fields) wh
This is possible with a monkey patch.
The following example will make the "note" field to be read only for existing AdminNote objects. Unlike converting fields to be hidden like suggested in other answers, this will actually remove fields from the submit/validation workflow (which is more secure and uses existing field renderers).
#
# app/models.py
#
class Order(models.Model):
pass
class AdminNote(models.Model):
order = models.ForeignKey(Order)
time = models.DateTimeField(auto_now_add=True)
note = models.TextField()
#
# app/admin.py
#
import monkey_patches.admin_fieldset
...
class AdminNoteForm(forms.ModelForm):
class Meta:
model = AdminNote
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.get_readonly_fields():
del self.fields[field]
def get_readonly_fields(self):
if self.instance.pk:
return ['note']
return []
class AdminNoteInline(admin.TabularInline):
model = AdminNote
form = AdminNoteForm
extra = 1
fields = 'note', 'time'
readonly_fields = 'time',
@admin.register(Order)
class OrderAdmin(admin.ModelAdmin):
inlines = AdminNoteInline,
#
# monkey_patches/admin_fieldset.py
#
import django.contrib.admin.helpers
class Fieldline(django.contrib.admin.helpers.Fieldline):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if hasattr(self.form, 'get_readonly_fields'):
self.readonly_fields = list(self.readonly_fields) + list(self.form.get_readonly_fields())
django.contrib.admin.helpers.Fieldline = Fieldline