Django: Ticket #16693: Unregistering ModelAdmin view and registering it again changing its contents is not realized when invoking it.https://code.djangoproject.com/ticket/16693
<p>
When trying to make a change to the list_per_page option of a ModelAdmin class instance,
it seems that the change is not activated on the fly.
I first "unregister" the old ModelAdmin class and then "register" a new one (which is actually created)
but when trying to invoke the view, the old one is used, it looks like it is cached somewhere and the url-mechanism
is not using the re-created view, but invokes the old one.
</p>
<p>
After some investigation, I managed to create a work around that demonstrates what might be a bug,
see the code snippets, especially the "changelist_view" function - if it is omitted,
the behavior I am describing happens.
</p>
<p>
Here are code snippets that demonstrate this:
</p>
<pre class="wiki"># settings.py
...
FLIGHTADMININSTANCE = None
...
</pre><pre class="wiki"># myapp/admin.py
...
from django.conf import settings
from myapp.models import ConfigParameters
...
class FlightAdmin(admin.ModelAdmin):
try:
list_per_page = int(ConfigParameters.objects.get(name="FLIGHTADMIN_LIST_PER_PAGE").value)
except:
list_per_page = 5;
...
def __init__(self, *args, **kwargs):
super(FlightAdmin, self).__init__(*args, **kwargs)
# store globally the object instance pointer
settings.FLIGHTADMININSTANCE = self
# following debug shows that the list_per_page is really changed
print "FlightAdmin created", self, self.list_per_page
def changelist_view(self, request, extra_context=None, **kwargs):
# NOTE: following is to override some probably cached instance of the view
# and enables the changed view to be used instead of the first instance created
# of the FlightAdmin class if this hook is not used
return super(FlightAdmin, settings.FLIGHTADMININSTANCE).changelist_view(request, extra_context=extra_context)
...
admin.site.register(Flight, FlightAdmin)
...
def list_per_page_change(sender, instance, created, **kwargs):
if instance.name == 'FLIGHTADMIN_LIST_PER_PAGE':
# yes - the value is changing, change the FlightAdmin class accordingly
admin.site.unregister(Flight)
try:
admin.site.register(Flight, FlightAdmin, list_per_page=int(instance.value))
except:
admin.site.register(Flight, FlightAdmin)
post_save.connect (list_per_page_change, sender=ConfigParameters)
</pre>en-usDjangohttps://www.djangoproject.com/s/img/site/hdr_logo.gifhttps://code.djangoproject.com/ticket/16693
Trac 1.0.7aaugustinThu, 25 Aug 2011 18:52:43 GMTstatus changed; needs_docs, resolution, needs_tests, needs_better_patch sethttps://code.djangoproject.com/ticket/16693#comment:1
https://code.djangoproject.com/ticket/16693#comment:1
<ul>
<li><strong>status</strong>
changed from <em>new</em> to <em>closed</em>
</li>
<li><strong>needs_docs</strong>
unset
</li>
<li><strong>resolution</strong>
set to <em>invalid</em>
</li>
<li><strong>needs_tests</strong>
unset
</li>
<li><strong>needs_better_patch</strong>
unset
</li>
</ul>
<p>
You shouldn't modify settings at runtime — never. The docs couldn't be more clear: <a class="ext-link" href="https://docs.djangoproject.com/en/dev/topics/settings/#altering-settings-at-runtime"><span class="icon">​</span>https://docs.djangoproject.com/en/dev/topics/settings/#altering-settings-at-runtime</a>
</p>
<p>
Even if your code worked, the settings would only be updated in the current process. On a multiprocess webserver (anything but the built-in dev server) you will have different settings in each process, and you will obtain random results, depending on which process handles your request. On a threaded webserver, you would get race conditions between <tt>settings.FLIGHTADMININSTANCE = self</tt> and <tt>super(FlightAdmin, settings.FLIGHTADMININSTANCE)</tt>, which is likely to break in horrible ways.
</p>
<p>
Finally, <tt>unregister</tt> is undocumented; there's no commitment on what it does.
</p>
<hr />
<p>
To sum up, I'm sorry, but your code has such fundamental problems that I can't figure out if there's really a problem in Django. If you can demonstrate that Django doesn't behave according to its documentation or reasonable expectations, please reopen the ticket.
</p>
Ticketheidar_rafnTue, 30 Aug 2011 15:10:42 GMThttps://code.djangoproject.com/ticket/16693#comment:2
https://code.djangoproject.com/ticket/16693#comment:2
<p>
Thanks for the comments. My problem to solve was to allow the user to configure the
<tt> ModelAdmin.list_per_page </tt> option, but I obviously did not describe it well enough and I did not read the documentation thoroughly enough in order to find the easy solution. <br />
This problem is actually very easy to solve with the documented "ModelAdmin.changelist_view(self, request, extra_context=None)" option like this:
</p>
<pre class="wiki"> def changelist_view(self, request, extra_context=None, **kwargs):
try:
self.list_per_page = int(ConfigParameters.objects.get(name="FLIGHTADMIN_LIST_PER_PAGE").value)
except:
self.list_per_page = 5;
return super(FlightAdmin, self).changelist_view(request, extra_context=extra_context)
</pre>
Ticket