Невозможно вызвать ModelAdmin.change_view (), данные ManagementForm отсутствуют - PullRequest
0 голосов
/ 25 марта 2019

Я программирую сайт, который отображает события.Каждое возникновение события является его собственным объектом.Поскольку многие из событий повторяются и утомительно вводить все заново и просто изменять дату, я добавил генератор событий, чтобы пользователь мог задать имя, местоположение и время, а затем выбрать несколько дат длякакие вхождения могут быть сгенерированы с помощью этих свойств.

Я интегрировал форму для генератора вхождений в представление изменений на странице администратора события.Мне даже удалось заставить это работать, даже при том, что я столкнулся с большим количеством ошибок типа вредных и сбоев, связанных с типом.(Мне бы очень хотелось, чтобы у Django были подсказки типа.)

Однако, если отправленная форма генератора вхождений недействительна, Django неправильно отображает представление изменений.Вылетает с ошибкой проверки, ['ManagementForm data is missing or has been tampered with'].Я попытался просмотреть след, но я не мог понять, что его вызывает.Я просто передаю недопустимую форму как extra_context, чтобы на странице отображались ошибки пользователя.

admin.py

class EventAdmin(admin.ModelAdmin):
    inlines = [OccurrenceInline]
    change_form_template = "admin/event_change_form.html"

    def change_view(self, request, object_id, form_url="", extra_context={}):
        extra_context["generator_form"] = extra_context.get(
            "generator_form",
            OccurrenceGeneratorForm(initial={"event": Event.objects.get(pk=object_id)}),
        )

        return super().change_view(request, object_id, form_url, extra_context)

    def get_urls(self):
        urls = super().get_urls()
        extra_urls = [path("<path:object_id>/generator/", self.generator_view)]
        return extra_urls + urls

    def generator_view(self, request, object_id, *args, **kwargs):
        if request.method == "POST":
            form = OccurrenceGeneratorForm(request.POST)
            if form.is_valid():
                self.generate_occurrences(form.cleaned_data)
            else:
                extra_context = {"generator_form": form}
                return self.change_view(request, object_id, extra_context=extra_context)

        return self.change_view(request, object_id)

    def generate_occurrences(self, data):
        Occurrence.objects.bulk_create(
            [
                Occurrence(
                    event=data["event"],
                    location=data["location"],
                    start_date=date,
                    start_time=data["start_time"],
                    duration_in_minutes=data["duration_in_minutes"],
                )
                for date in data["dates"]
            ]
        )

Шаблон является копи-пастойстандартного шаблона представления изменений, с добавленной внизу моей пользовательской формой генератора вхождений.

templates/admin/event_change_form.html

{% extends "admin/change_form.html" %}
{% load i18n admin_urls static admin_modify %}

{% block content %}<div id="content-main">
    {% block object-tools %}
    {% if change %}{% if not is_popup %}
    <ul class="object-tools">
        {% block object-tools-items %}
        {% change_form_object_tools %}
        {% endblock %}
    </ul>
    {% endif %}{% endif %}
    {% endblock %}
    <form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="{{ form_url }}" method="post"
        id="{{ opts.model_name }}_form" novalidate>{% csrf_token %}{% block form_top %}{% endblock %}
        <div>
            {% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1">{% endif %}
            {% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}">{% endif %}
            {% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %}
            {% if errors %}
            <p class="errornote">
                {% if errors|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %}
            </p>
            {{ adminform.form.non_field_errors }}
            {% endif %}

            {% block field_sets %}
            {% for fieldset in adminform %}
            {% include "admin/includes/fieldset.html" %}
            {% endfor %}
            {% endblock %}

            {% block after_field_sets %}{% endblock %}

            {% block inline_field_sets %}
            {% for inline_admin_formset in inline_admin_formsets %}
            {% include inline_admin_formset.opts.template %}
            {% endfor %}
            {% endblock %}

            {% block after_related_objects %}{% endblock %}

            {% block submit_buttons_bottom %}{% submit_row %}{% endblock %}

            {% block admin_change_form_document_ready %}
            <script type="text/javascript" id="django-admin-form-add-constants"
                src="{% static 'admin/js/change_form.js' %}" {% if adminform and add %}
                data-model-name="{{ opts.model_name }}" {% endif %}>
                </script>
            {% endblock %}

            {# JavaScript for prepopulated fields #}
            {% prepopulated_fields_js %}

        </div>
    </form>

    <details style="margin-bottom: 30px; padding: 10px; border: 1px solid lightgray;">
        <summary>
            <h2 style="display: inline;">Occurrence Generator</h2>
        </summary>
        <div id="occurrence-generator" style="margin-top: 10px;">
            {{ generator_form.media }}
            <form method="post" action="../generator/">{% csrf_token %}
                {{ generator_form.as_p }}
                <input type="submit" value="Generator occurrences">
            </form>
        </div>
    </details>
</div>
{% endblock %}

Есть ли что-то очевидное, что я здесь ошибся?Я действительно понятия не имею, откуда обычно берется форма и как я могу ее получить или предоставить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...