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) which works fine, but turns the field into a label when clicking 'Add another item' instead of a dropdown.
Is there a way to keep a field readonly, but still allow new items to be created with the proper field input?
Thanks!
Thomas
Edit: Managed to figure it out by way of a custom widget
class ReadOnlySelectWidget(forms.Select): def render(self, name, value, attrs=None): if value: final_attrs = self.build_attrs(attrs, name=name) output = u'<input value="%s" type="hidden" %s />' % (value, flatatt(final_attrs)) return mark_safe(output + str(self.choices.queryset.get(id=value))) else: return super(ReadOnlySelectWidget, self).render(name, value, attrs)
It just turns it into a hidden if there is a value, won't work in every situation (only really works with 1 read only field).
Having the same problem, I came across this fix:
Create two inline objects, one with no change permission, and the other with all the fields read-only. Include both in the model admin.
class SubscriptionInline(admin.TabularInline): model = Subscription extra = 0 readonly_fields = ['subscription', 'usedPtsStr', 'isActive', 'activationDate', 'purchaseDate'] def has_add_permission(self, request): return False class AddSupscriptionInline(admin.TabularInline): model = Subscription extra = 0 fields = ['subscription', 'usedPoints', 'isActive', 'activationDate', 'purchaseDate'] def has_change_permission(self, request, obj=None): return False # For Django Version > 2.1 there is a "view permission" that needs to be disabled too (https://docs.djangoproject.com/en/2.2/releases/2.1/#what-s-new-in-django-2-1) def has_view_permission(self, request, obj=None): return False
Include them in the same model admin:
class UserAdmin(admin.ModelAdmin): inlines = [ AddSupscriptionInline, SubscriptionInline]
To add a new subscription I use the AddSubscriptionInline
in the admin. Once it is saved, the new subscription disappears from that inline, but now does appear in the SubscriptionInline
, as read only.
For SubscriptionInline
, it is important to mention extra = 0
, so it won't show junk read-only subscriptions. It is better also to hide the add option for SubscriptionInline
, to allow adding only via AddSubscriptionInline
, by setting the has_add_permission
to always return False
.
Not perfect at all, but it's the best option for me, since I must provide the ability to add subscriptions on the user admin page, but after one is added, it should be changed only via the internal app logic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With