First a little background:
I have an Event
model that has various event_type
s. I want to break one of those event types, \'Film\', into it\'s o
You could override the queryset-method of your EventModelAdmin
and filter the queryset so that Film-Events get excluded.
Something similar to this:
class EventAdmin(admin.ModelAdmin):
def queryset(self, request):
qs = super(EventAdmin, self).queryset(request)
return qs.exclude(event_type='film')
Looking at the Django source, the admin URLs are built in two places, in the ModelAdmin
instances, and in the AdminSite
instances.
The part you want to change is built in the AdminSite instance (django.contrib.admin.sites.AdminSite
), you can subclass that and override the get_urls
method. If you look at the second half of the method you'll see this:
# Add in each model's views. for model, model_admin in self._registry.iteritems(): urlpatterns += patterns('', url(r'^%s/%s/' % (model._meta.app_label, model._meta.module_name), include(model_admin.urls)) )
There it is adding the model's ._meta.module_name which is just the model's name lowercased (django.db.models.options.Options.contribute_to_class
).
An easy way out is to override the Site's get_urls
method and add a dict or special case for the Proxy model so it uses a different url instead of model._meta.module_name
, something along the lines:
class MyAdminSite(AdminSite):
module_name_dict = { EventAdminProxy: 'myfunkymodulename' } def get_urls(self): base_patterns = super(MyAdminSite, self).get_urls() my_patterns = patterns('',) for model, model_admin in self._registry.iteritems(): if model in self.module_name_dict: module_name = self.module_name_dict[model] my_patterns += patterns('', url(r'^%s/%s/' % (model._meta.app_label, module_name), include(model_admin.urls)) ) return my_patterns + base_patterns
You could also subclass ChangeList
and override the url_for_result()
method to customise change urls, (learned from another answer), e.g.:
from django.contrib.admin.views.main import ChangeList
class FooChangeList(ChangeList):
def url_for_result(self, obj):
return '/foos/foo/{obj.pk}/'
class FooAdmin(admin.ModelAdmin):
def get_changelist(self, request, **kwargs):
return FooChangeList
Adapted example for the question:
from django.contrib.admin.views.main import ChangeList
from django.urls import reverse
class FilmAdmin(admin.ModelAdmin):
def get_changelist(self, request, **kwargs):
class FilmChangeList(ChangeList):
def url_for_result(self, obj):
return reverse('admin:events_event_change', args=(obj.pk, ))
return FilmChangeList