Почему моя django-crispy AdminForm не может разрешить URL AdminSite?
Настройка
Я определил новый url администратора:
from django.contrib.admin import AdminSite
from django.http import HttpResponse
from django.urls import path
class MyAdminSite(AdminSite):
def get_urls(self):
from django.urls import path
urls = super().get_urls()
urls += [
path(
"generate",
admin_site.admin_view(self.my_view),
name="generate",
)
]
return urls
def my_view(self, request):
print(request.data)
return HttpResponse("Hello!")
admin_site = MyAdminSite()
url успешно зарегистрирован:
print(admin_site.get_urls())
[ ..., ..., <URLPattern 'generate' [name='generate']>] # <-- here!
Теперь в моем django-crispy-form
мне нужно добавить действие формы для нескольких кнопок отправки. Библиотека не позволяет задавать несколько действий формы, поэтому мне пришлось отключить тег формы и добавить новый вручную:
class PromptForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper() # django-crispy-forms
self.helper.form_method = 'post'
self.helper.form_tag = False # <-- disable form_tag
# Form layout
self.helper.layout = Layout(
# Add new form_tag
HTML("""<form action="{% url 'admin:generate' %}"><input type="submit" class="btn btn-success" value="generate"></form>"""),
)
Выпуск
Оба {% url 'generate' %}
и {% url 'admin:generate' %}
не могут установить обратное соответствие новому url:
`django.urls.exceptions.NoReverseMatch: Reverse for 'generate' not found. 'generate' is not a valid view function or pattern name.
Решение
Добавьте пользовательское действие к url /admin/.../change
, переопределив django.contrib.admin.options.ModelAdmin._changeform_view
:
from django.contrib import admin
class MyModelAdmin(admin.ModelAdmin):
def _changeform_view(self, request, object_id, form_url, extra_context):
if '<your-action>' in request:
# 1. check permissions
# 2. do your thing
print(request)
return super()._changeform_view(request, object_id, form_url, extra_context)
Теперь вы можете добавить простую кнопку sumbit в свою форму с помощью пользовательского действия:
<input type="submit" name="<your-action>" value="<button-title>">
Преимущество
- Нулевой javascript.
- Аутентификация защищена.
- Все действия администратора будут работать с вашей формой (добавить, сохранить и продолжить, ...)