Ошибка запуска промежуточного программного обеспечения дважды в django

У меня есть промежуточное программное обеспечение, которое я создал для приложения, которое проверяет несколько критериев для вошедшего в систему пользователя.

Если он терпит неудачу любого из них, он запускает ошибки, сообщая пользователю.

Проблема в том, что ошибка появляется дважды вверху страницы.

Промежуточное ПО выглядит так:

class RegistrationMiddleware(object):

    def __init__(self, get_response):
        self.get_response = get_response
        print("In init of middleware")

    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.
        print("Pre-view middle")
        response = self.get_response(request)
        # Code to be executed for each request/response after
        # the view is called.
        print("Post-view middle")

        ...logic stuff....

        if invalid_entries:
            for problem_reg in invalid_entries:
                messages.error(
                    request, format_html(
                        """
                        Please either
                        remove or change this registration.
                        """ 
                        )
                    )
        print('end of view reutrning response')
        return response

Ошибка появляется дважды на странице.

Моя консоль показывает что-то вроде этого:

Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
In init of middleware
Pre-view middle
this is a test of the get_user method
Post-view middle
end of view reutrning response
[25/Feb/2019 09:48:46] "GET /registrations/ HTTP/1.1" 200 21860
[25/Feb/2019 09:48:46] "GET /static/styles.css HTTP/1.1" 200 7082
[25/Feb/2019 09:48:46] "GET /static/registrations/style.css HTTP/1.1" 200 2282
[25/Feb/2019 09:48:46] "GET /static/registrations/index.js HTTP/1.1" 200 1885
[25/Feb/2019 09:48:46] "GET /static/all.min.js HTTP/1.1" 200 3738182
Pre-view middle
Post-view middle
this is a test of the get_user method
end of view reutrning response
Not Found: /favicon.ico
[25/Feb/2019 09:48:47] "GET /favicon.ico HTTP/1.1" 404 2586

Я не уверен, что промежуточное ПО является на 100 % лучшим решением для проверки подобных ошибок, но мне нужно проверить один и тот же фрагмент кода практически в каждом представлении в приложении, поэтому мне кажется, что это правильный способ справиться с этим.

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

    {% for message in messages %}
        <div class = "alert alert-{{ message.tags }} alert-dismissible mt-4" role = "alert">
            <button type = "button" class = "close" data-dismiss = "alert" aria-label = "Close">
                <span aria-hidden = "true">&times;</span>
            </button>
            {{ message }}
        </div>
    {% endfor %}

Судя по вашим журналам, ваше промежуточное ПО работает правильно. Я не уверен, что вы имеете в виду под ошибкой, показывающей дважды одну страницу... как вы показываете ошибки на странице? Возможно ли, что у вас есть несколько предметов в invalid_entries?

Nikolas Stevenson-Molnar 25.02.2019 17:01

Нет — в моей среде разработки я настроил его, поэтому в invalid_entries отображается только 1, но когда я обновляю страницу — это сообщение об ошибке отображается дважды на экране. В шаблоне это простой цикл {% for message in messages %}

Hanny 25.02.2019 17:05

Вы проверили значения messages перед возвратом из промежуточного программного обеспечения выше?

Nikolas Stevenson-Molnar 25.02.2019 17:08

Отрицательный. В настоящее время у меня нет проверок существующих сообщений.

Hanny 25.02.2019 17:16

Вроде что-то с загрузкой страницы в первый раз: например, захожу на страницу А, вижу дублирование ошибок. Затем на странице B я вижу 2 ошибки. Вернуться на страницу А? Я вижу только один, как и ожидалось. Вот почему я пытался просто назвать это «один раз», так сказать. Я чувствую, что иногда его вызывают дважды.

Hanny 25.02.2019 17:18

Хорошо, возможно, стоит проверить сообщения в конце промежуточного программного обеспечения с помощью print(get_messages(request)).

Nikolas Stevenson-Molnar 25.02.2019 17:19

При осмотре - вижу, что это всего одно сообщение. Я думаю, проблема в том, что одно и то же сообщение добавляется дважды — например, в моем журнале консоли выше вы видите, что строка end of view returning response срабатывает дважды для одного вызова на сервер (один раз перед строками GET, один раз после). Это означает, что ошибка добавляется к сообщениям «дважды», верно?

Hanny 25.02.2019 17:26

На самом деле в вашем журнале запрашиваются две отдельные страницы. Второй /favicon.ico. Ваше промежуточное ПО обрабатывает все запросы, даже если URL-адрес не существует.

Nikolas Stevenson-Molnar 25.02.2019 17:28

Не могли бы вы добавить свой код шаблона (где вы отображаете ошибки) к своему вопросу?

Nikolas Stevenson-Molnar 25.02.2019 17:29

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

Hanny 25.02.2019 17:33

Да, это может быть. Фавикон активирует ваше промежуточное ПО, но поскольку шаблон не отображается, сообщения не повторяются и, следовательно, не отклоняются. Затем при следующем запросе вы получите несколько сообщений.

Nikolas Stevenson-Molnar 25.02.2019 17:38

Да, непоследовательность меня убивает. Может быть, промежуточное программное обеспечение и не является решением, но я уверен, что в данном случае это так. Просто расстраивает, потому что это очень «иногда это дважды, иногда нет» - я ценю вашу помощь в устранении неполадок :)

Hanny 25.02.2019 18:03

Давайте продолжить обсуждение в чате.

Nikolas Stevenson-Molnar 25.02.2019 18:04
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
13
259
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Логика после: response = self.get_response(request) вызывала проблему и непоследовательное поведение — потому что оповещение обрабатывалось после представления, что, в свою очередь, вызывало загрузку ошибки при обновлении следующий, очистке и повторении, и большую часть времени ошибка дублировалась.

Переместив его в до, обработка представления устранила проблему и помогла сделать ее согласованной.

Другие вопросы по теме