I'm experiencing a curious problem with Django's admin system and overriding the add_view and change_view methods to display different fields for adding and changing data. The add view works perfectly until the change view is displayed, then after that it will always display the change view instead of the add view when trying to add new data. I am using the latest release version of Django 1.9.4. My ModelAdmin class is quite simple:
@admin.register(Trigger)
class TriggerAdmin(admin.ModelAdmin):
def add_view(self, request, **kwargs):
self.fields = ('name', 'modules', 'trigger_event')
self.filter_horizontal = ('modules',)
return super(TriggerAdmin, self).add_view(request, **kwargs)
def response_add(self, request, obj, **kwargs):
return HttpResponseRedirect("../%s" % obj.id)
def change_view(self, request, object_id, **kwargs):
self.fieldsets = (
(None, {'fields': ('name', 'modules')}),
(_('Trigger'), {'fields': ('trigger_event', 'query', 'actions', 'is_active')})
)
self.readonly_fields = ('modules', 'trigger_event')
return super(TriggerAdmin, self).change_view(request, object_id, **kwargs)
I have disabled all 3rd party apps and am only using the DummyCache. The only way to get the add view to show again after the change view has been displayed is to restart the site. I have checked that it is correctly calling the add_view method, its just going wrong at some point after that and showing the change_view instead.
I assume this is not a bug otherwise there would be others complaining about it, so I must be doing something wrong but I cannot see what it is.
Thanks,
Paul
It isn't safe to modify self.fields
, self.fieldsets
and self.readonly_fields
like this. You are changing them for future requests as well as the current one.
Instead of modifying these attributes in the add_view
and change_view
methods, you can override the get_fields
, get_fieldsets
, and get_readonly_fields
instead. If the obj
is None, then you are adding an object. For example:
def get_fields(self, request, obj=None):
if obj is None:
return [<fields for add view>]
else:
return [<fields for change view>]