Генерал Венделер обладал редким даром излагать свои решения в краткой, ясной и доходчивой форме. (С) х/ф "Приключения принца Флоризеля." Коллега обратился с запросом. "Хочу забрать в свой уютный екзель данные с корпоративного сайта прямо в том виде, как я их там отфильтровал и отсортировал.  Кнопку такую хочу рядом с табличкой сайта." Сайт сделан на админке Django. Будем реализовывать это лапидарное ТЗ от коллеги. Таблица, из которой нужно выгрузить данные, расположена на сайте по адресу http://example.com/admin/telemetry/data/. Вьюшка должна быть не "отдельно стоящей", а вписанной в контекст админки.  Т.е. иметь (например) адрес http://example.com/admin/telemetry/data/csv и подчиняться всем требованиям настроек админки по безопасности, разделению полномочий пользователей и т.п. Для этой цели в ModelAdmin предусмотрена функция get_urls, переопределив которую, можно добавлять свои вьюшки в схему адресов админки. Разместить на нужной странице админки ссылку на нашу вьюшку можно с помощью механизма переопределения шаблонов. В каталоге шаблонов нашего сайта нужно создать шаблон, расширяющий стандартный шаблон админки Django.  Он должен располагаться в каталоге templates/admin/telemetry/data/ и называться change_list.html. В settigs.py нужно расположить ссылку на наш каталог templates перед ссылкой на каталог с шаблонами админки. Тогда Django найдет наш шаблон с добавленной ссылкой первым и будет использовать именно его. Должен сказать, что данный механизм с расположением шаблона в определенном месте дерева каталогов я не проверял.  В реальном проекте используется прямое указание имени шаблона, т.к. там присутствуют не относящиеся к рассматриваемой теме фичи. Но, по заверениям документации Djano, описанный выше механизм должен работать. В коде шаблоне мы наследуем шаблон Django для таблицы объектов и добавляем html код со ссылкой на нашу вьюшку над содержимым блока content. В приведенном выше коде шаблона присутствует один важный момент. Вот этот:  {{ request.GET.urlencode }} Когда пользователь применяет фильтры и сортирует содержимое таблицы в админке, Django сохраняет эти настройки в виде параметров в командной строке браузера. Чтобы получить настройки фильтров и сортировок пользователя, нам нужно скопировать их как строку параметров нашей вьюшки выгрузки данных. И тут нас ожидает неприятный сюрприз. Штатная функция ModelAdmin.get_queryset возвращает набор данных без учета пользовательских фильтров и сортировок. Видимо они применяются после вызова этой функции к возвращенному результату. У нас остается два варианта действий. Обрабатывать переданные параметры GET-запроса и самостоятельно накладывать на queryset фильтры и сортировки, дублируя штатный механизм админки Django (ужас) Потупив глаза, объяснять суровому коллеге, что эээ ввиду некоторых ээээ технических особенностей устройства корпоративного сайта эээ ... (ужас-ужас) К счастью, третий вариант действий нашелся (как обычно) на stackoverflow. Класс django.contrib.admin.views.main.ChangeList располагается в иерархии выше ModelAdmin, учитывает все его варианты фильтров и сортировок и возвращает queryset с учетом их настроек. Критически настроенный читатель скажет, что это "грязный хак" и мы лезем "под капот" Django. Что в будущем интерфейсы этого внутреннего класса могут поменяться и наш код перестанет работать. Отчасти это так. С 2009 года там действительно кое-то поменялось. Немного изменились имена методов, добавились обязательные позиционные аргументы. Но в целом, если заглянуть в код Django, все достаточно понятно. В любом случае, для меня этот вариант был существенно лучше двух предыдущих. Поэтому переписываем код нашей вьюшки выгрузки данных следующим образом. Остается написать функцию queryset2csv для трансляции queryset в содержание выгружаемого csv-файла. Суровый коллега доволен, говорит: "Круто". Это типа похвала :)  Python разработчик