Закрыть

Для эффективной работы на сайте используются cookie и обработка персональных данных. Пользуясь этим сайтом, вы соглашаетесь с правилами использования сайта. Подробнее

Цитата дня

Vivazzi.ru

Личный сайт Мальцева Артема

Если ничего не помогает, прочтите документацию, наконец! (о программировании)
RaD

Воспроизвести ошибку в браузере, полученную на почте от Django

9 июля 2018 г. 0:26

Как правило, если возникает 500 ошибка вашего приложения на сервере, то посылается сгенерированный Django-отчёт об ошибке (трейсбек) электронным адресам, указанным в ADMINS в settings.py. Это может выглядеть примерно так:

Internal Server Error: /billing/online_reg_ip/

KeyError at /billing/online_reg_ip/
'birthday_day'

Request Method: POST
Request URL: https://valen-media.ru/billing/online_reg_ip/
Django Version: 1.10.7
Python Executable: /usr/bin/uwsgi-core
Python Version: 2.7.9
Python Path: ['/path_to_project/src/', '.', '', ...]
Server time: Ср, 21 Мар 2018 08:40:50 +0800
Installed Applications: (u'django.contrib.contenttypes', ...)
Installed Middleware: (u'django.middleware.cache.UpdateCacheMiddleware', ...)

Traceback: 
File "/path_to_projet/env/local/lib/python2.7/site-packages/django/core/handlers/exception.py" in inner
  42. response = get_response(request)
...
File "/path_to_projet/billing/forms.py" in clean
  100. del cleaned_data['birthday_day']

Exception Type: KeyError at /billing/online_reg_ip/
Exception Value: 'birthday_day'
Request information:
USER: AnonymousUser

POST:
comment = u'http://google01**.com/'
birthday_day = u'1980-12-12'
first_name = u'Hoz GT'
csrfmiddlewaretoken = 'f6p***'
...

COOKIES:
csrftoken = 'f6p***'

Это реальная ошибка моего клиентского проекта, которая пришла мне на почту (для сокращения я убрал ненужные части этого отчёта). По POST-данным видно, что форму заполнял робот, и радует: хоть не у реального клиента она возникла :)

Я быстро исправил ошибку, добавив проверку существования ключа в словаре, но как теперь протестировать? Забить вручную все POST-данные в форме? Это долго и тем более нужно будет тогда отключить проверку js, закомментировав строки в шаблоне. Поэтому лучше всё это дело автоматизировать.

В простейшем случае вы можете написать management-команду, которая отправит POST-данные на ваш локальный сервер по указанному пути и, получив данные, откроет в браузере страницу, в которой вы можете наглядно увидеть, что открывается именно ожидаемая страница:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.conf import settings
from django.core.management.base import BaseCommand

import requests
from os.path import join
import webbrowser


class Command(BaseCommand):
    def handle(self, *args, **options):

        url = 'http://localhost:8001/billing/online_reg_ip/'

        data = dict(comment=u'http://google01**.com/',
                    birthday_day=u'1980-12-12',
                    first_name=u'HolaBromz GT',
                    csrfmiddlewaretoken=u'f6p***',
                    ...)

        client = requests.session()
        client.get(url)

        data['csrfmiddlewaretoken'] = client.cookies['csrftoken']
        r = client.post(url, data)

        path = join(settings.MEDIA_ROOT, 'test.html')
        with open(path, 'w') as f:
            f.write(r.text.encode('utf-8'))

        webbrowser.open('file://{}'.format(path))

С помощью этой простой команды вы можете проверять нужный url с POST-данными.

Обратите внимание, что мы должны получить свой csrftoken, а не использовать тот, который использовал робот. В противном случае на локальной машине вы получите ответ сервера 403 Forbidden. Чтобы избежать эту ошибку, нам нужно открыть сессию requests.session() и получить любой url, чтобы наш client сохранил данные cookie. Когда данные получены, остаётся заменить значение ключа csrfmiddlewaretoken в отправляемых данных.

Для удобства полученные данные сервера я сохраняю в файле test.html в папку media (эта папка соответствует значению переменной MEDIA в settings.py), чтобы проверяемая страница test.html случайно не попала в репозиторий. В .hgignore у меня настроено так, что только placeholder в папке media попадает в репозиторий:

...
syntax: regexp
media/(?!placeholder)
...

Полученный файл автоматом открываем в браузере командой webbrowser.open().

И наконец, чтобы на странице отображалась статика, я использую следующие настройки:

MEDIA_ROOT = os.path.join(ROOT_DIR, 'media')
MEDIA_URL = '/media/' if not DEBUG else ''

STATIC_ROOT = os.path.join(ROOT_DIR, 'collect_static')
STATIC_URL = '/static/' if not DEBUG else '../collect_static/'

 

Для меня пока выше написанного кода достаточно для тестирования. Возможно, есть хорошие инструменты, которые ещё удобнее. Подозреваю, что есть приложение, позволяющее в админке отображать ошибки и удобно тестировать с разными POST-данными. Если знаете, поделитесь ;)

Оцените статью

0 из 5 (всего 0 оценок)

Поля, отмеченные звёздочкой ( * ) , являются обязательными.

Спасибо за ваш отзыв!

Автор статьи

Права на использование данной статьи, расположенной на настоящей странице http://vivazzi.ru/it/error-reproducing/:

Разрешается копировать статью с указанием её автора и ссылки на оригинал без использования параметра rel="nofollow" в теге <a>. Использование:

Автор статьи: Мальцев Артём
Ссылка на статью: <a href="http://vivazzi.ru/it/error-reproducing/">http://vivazzi.ru/it/error-reproducing/</a>

Подробнее: Правила использования сайта

Вам нужно саморазвиваться или вы хотите зарабатывать деньги?

Или вы ищите хорошие IT сервисы или книги? Сохраните свое время и взгляните на мою подборку рекомендаций, которыми постоянно пользуюсь.
Посмотреть рекомендации

Комментариев: 0

Вы можете оставить комментарий как незарегистрированный пользователь. Но, зарегистрировавшись, вы сможете получать оповещения об ответах, а также иметь доступ к своему личному аккаунту для просмотра своих комментариев.

Чтобы оставить комментарий от своего имени войдите или зарегистрируйтесь обычным способом или через социальные сети:

Отправить

На данный момент нет специального поиска, поэтому я предлагаю воспользоваться обычной поисковой системой, например, Google, добавив "vivazzi" после своего запроса.

Попробуйте