I fixed error with param capture in url by overriding admin_view method in custom AdminSite. But unfortunately there is no way to fix errors from reverse url lookup because admin site knows nothing about param. After some investigation I found a way to workaround that problem with additional middleware class. Whole solution:
urls.py
url(r'^manage-board/', include(board_admin.urls)),
middleware.py
import re
r = re.compile(r'^/manage-board/(?P<board_slug>[-\w]+)/')
class AdminMiddleware(object):
def process_request(self, request):
match=r.search(request.path)
if match:
match = match.groupdict()
request.board_slug = match.get('board_slug')
request.path = request.path.replace('manage-board/'+ request.board_slug,'manage-board')
request.path_info = request.path_info.replace('manage-board/'+ request.board_slug,'manage-board')
def process_response(self, request, response):
if hasattr(request, 'board_slug'):
response.content = response.content.decode('utf-8').replace("/manage-board/", u"/manage-board/%s/" % request.board_slug).encode('utf-8')
return response
admin.py
class BoardModelAdmin(admin.ModelAdmin):
exclude = ('board',)
def queryset(self, request):
qs = super(BoardModelAdmin, self).queryset(request)
if hasattr(request, 'board_slug'):
return qs.filter(board__slug = request.board_slug)
else:
return qs
def save_model(self, request, obj, form, change):
if hasattr(request, 'board_slug'):
obj.board = Baord.objects.get(slug = request.board_slug)
super(BoardModelAdmin, self).save_model(request, obj, form, change)
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "category" and hasattr(request, 'board_slug'):
kwargs["queryset"] = Category.objects.filter(board__slug=request.board_slug)
return super(BoardModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
class BoardRelatedFieldListFilter(RelatedFieldListFilter):
def __init__(self, field, request, params, model, model_admin, field_path):
super(BoardRelatedFieldListFilter, self).__init__(field, request, params, model, model_admin, field_path)
if hasattr(request, 'board_slug'):
self.lookup_choices = [(instance.pk, smart_unicode(instance)) for instance in field.rel.to.objects.filter(board__slug=request.board_slug)]
class MessageAdmin(BoardModelAdmin):
list_filter = [('category', BoardRelatedFieldListFilter)]