Django Admin changeelist submit redirect
Можно ли сделать так, чтобы django перенаправлял на другую страницу после отправки изменений непосредственно в представлении списка изменений? (После указания полей list_editable
)
Уже пытался использовать различные методы response_post_save_change
, response_change
или response_add
, но ни один из них не сработал.
Я подозреваю, что это может быть внутри change_view
, не уверен, как с этим бороться, поскольку он обрабатывает сохранение формы.
Вы правы, вам нужно переопределить метод changelist_view
в вашем классе администратора. Этот метод возвращает объект, похожий на ответ, и это значение определенно можно настроить.
Прием №1: скопируйте весь метод ModelAdmin.changelist_view
в свой собственный класс администратора, а затем измените его в соответствии со своими потребностями. Вероятно, это самый безопасный вариант для вашей ситуации, даже если вы измените только одну единственную строку кода в этом методе (который на данный момент состоит из 99 строк ).
class MyAdmin(admin.ModelAdmin):
@csrf_protect_m
def changelist_view(self, request, extra_context=None):
"""
The 'change list' admin view for this model.
"""
... omitting code that leads up to line 1756 (v3.2) ...
# Handle POSTed bulk-edit data.
if request.method == 'POST' and cl.list_editable and '_save' in request.POST:
... omitting more code ...
# This is it. Line 1785: change this to meet your needs
return HttpResponseRedirect(request.get_full_path())
... omitting the rest of the code after this line ...
Подход №2: вызывайте его через super()
, а затем проверяйте/изменяйте результаты. Это может потенциально быть ненадежным (комментарии в коде), но вот как это будет выглядеть:
class MyAdmin(admin.ModelAdmin):
def changelist_view(self, request, extra_context=None):
request_full_path = request.get_full_path()
response = super().changelist_view(request, extra_context)
# This is not a foolproof condition! In the changelist_view method, you can
# see that it returns this redirect in the following scenarios:
# - if action_failed (line ~1745 in django.contrib.admin.options, v3.2)
# - successful bulk update of the changelist (this is the use case you're targeting)
if isinstance(response, HttpResponseRedirect) and response.location == request_full_path:
# do something here, like return a redirect to a different URL
return HttpResponseRedirect(reverse('my_url_name'))
return response
Так что я не уверен, как вы определите которое из двух условий заставило его вернуть объект HttpResponseRedirect
с точно такими же параметрами (те же status_code
и те же location
) - одно из них является неудачей отправки, другое - успехом отправки! Но, возможно, у вас есть какой-то способ сделать это в вашем приложении, поэтому я оставлю это на потом.
Я бы сам выбрал подход №1, хотя мне определенно не нравится количество кода, который нужно копировать в свою собственную кодовую базу, и необходимость поддерживать его / думать о нем в будущем. Но, вероятно, это лучший способ.