Django создает пустые страницы при отправке данных POST и доступе к моделям - PullRequest
2 голосов
/ 21 мая 2011

Я тяну волосы за это. Я разрабатываю веб-приложение в Django 1.3 (недавно обновленное с 1.2.5 в слабой надежде, что это может решить мою ошибку), и я столкнулся с странной ошибкой в ​​одном из моих представлений.

Представление вызывается как AJAX-запрос от клиента. Если я называю представление GET-запросом, все в порядке. Если я называю это как POST-запрос без данных, все в порядке. Но если я назову это POST и включу данные (независимо от того, что это за данные), Django возвращает пустую страницу.

Будучи любопытным, я обнаружил, что могу печатать из своего представления и получать выходные данные в консоли отладки, поэтому я приступил к работе и обнаружил эту странную странность:

c = Character.objects.get (id = int (символ))

Это первая строка кода в этом представлении, которая имеет дело с моделью. Печать показывает, что символ не только является нормальным значением (это идентификатор, передаваемый запросом), но и в действительности получает правильную запись в базе данных. В любом случае, если эта строка вызывается, вывод Django для запроса будет zilch. Нада. Ничего такого.

Если я вернусь рано, прежде чем что-то делать с моими моделями, Django правильно выполнит остальную часть запроса. Что-то с моделями приводит к отправке ответа 200, но содержимое, похоже, опущено.

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

Это само представление, которое вызывается прямо из urls.py:

.
@csrf_exempt
def ajax_update(request, character):
    #determine the timestamp to send the client *before* polling
    #the database

    update_time = int(time.time())

    #grab each update... thingy as json, and put it all together
    output = {
        "events": current_events(request, character, "default"),
        "character": character,
        "update_time": update_time,
    }

    return HttpResponse(json.dumps(output), mimetype = "application/json")

Это код current_events, который содержит упомянутую строку:

def current_events(request, character, type = "default", timestamp = 0):
    '''
    purpose: grab the last 3 days worth of events, or the last 10 events,
    whichever is a larger list.
    '''

    #TODO: actually do something with timestamp
    c = Character.objects.get(id=int(character))

    #DEBUG: What on earth is going on here?
    print c

    #TODO: See if this can be optimized into a single query
    event_links = EventLink.objects.filter(viewer=c)
    events = Event.objects.filter(id__in=event_links.values('event')).order_by('timestamp')

    t = loader.get_template('ajax/world-events.html')

    output = []

    for event in events:
        revisions = Event.objects.filter(original_event=event.id).order_by('timestamp')

        display_message = event.message

        history = []
        if len(revisions):
            history.append(event) #first item in the history is the original event
            history.extend(revisions)   
            display_message = history[-1].message

        output.append({
            "id": event.id,
            "writer": event.writer.id,
            "type": event.type,
            "timestamp": int(time.mktime(event.timestamp.timetuple())),
            "message": t.render(RequestContext(request, {"event_text": display_message, "event": event, "history": history}))
        })

    return output

И, наконец, это CoffeeScript, который вызывает код с помощью jQuery из клиента:

auto_refresh_abort = 0
last_server_timestamp = 0
window.update_display = ->  
    #ajax call to grab events from the server
    $.ajax 
        type: 'POST'
        url: "/ajax/update/"+window.active_character
        data: 
            "last_update": last_server_timestamp
        dataType: "json"
        success: (output) ->
            auto_refresh_abort = 0
            update_character_log output.events
        error: (XMLHttpRequest, textStatus, errorThrown) ->
            auto_refresh_abort += 1
            console.log XMLHttpRequest

    return null

Если вы думаете, что это поможет (это уже ЛОТ), я могу опубликовать любые другие необходимые примеры кода, например сам код модели. Я могу подтвердить, что Персонаж, который ищется в моих тестовых примерах, существует, и это просто стандартный идентификатор Django, я не делаю с ним ничего странного.

Заранее спасибо.

Обновление: по запросу, вот пример того, что должен содержать вывод:

{'update_time': 1305984080, 'character': u'1', 'events': /*snip*/}

Я проверил, что выполнение кода проходит полностью и что выходные данные, передаваемые в HttpResponse, содержат эти данные. Для хихиканья я вставил возврат «ВКУСНО» после строки, где я опрашиваю Символ, так что выходные данные должны быть:

{'update_time': 1305984080, 'character': u'1', 'events': 'TASTY'}

и подтвердил, что это работает. Я могу «напечатать вывод» на консоль отладки прямо перед HttpRequest, и это отображается.

Если я закомментирую строку, касающуюся Character, мой браузер получит эти данные в качестве содержимого запроса. Кроме того, если я оставлю код как есть и просто не отправлю данные POST, браузер получит правильные данные. Конкретный случай, когда происходит сбой, - это когда я манипулирую моделями после отправки данных POST от клиента - в этом случае браузер получает точно такие же заголовки HTTP, но без содержимого. Заголовки, которые он получает:

Content-Type:application/json
Date:Sat, 21 May 2011 13:29:38 GMT
Server:WSGIServer/0.1 Python/2.6

, но фактический контент не доставляется.

Ответы [ 2 ]

1 голос
/ 21 мая 2011

Думаю, я нашел свою проблему.Как только я подключил свое приложение к Apache и перестал использовать сервер разработки Django, ошибка bizzare исчезла.Ответы теперь всегда отправляются.

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

Кажется, что сервер разработки требователен к тому, какие HTTP-заголовки он делает, и не любитпринять для данных POST.Я отредактирую это более подробно, если когда-нибудь смогу определить, что именно вызывает проблему и при каких обстоятельствах.Временное исправление для меня заключалось в разработке с использованием Firefox, чьи заголовки, похоже, нравятся Django.Эта ошибка не влияет на производственную среду под Apache.

1 голос
/ 21 мая 2011

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

  1. начните с создания вашейзапросы с использованием curl или с помощью REST-клиента firefox плагин :

  2. Затем вы пишете код ответа, возвращающий жестко закодированные фиктивные ответы объекта, охватывающий пару случаев (или все случаи использования).случаев).Таким образом, ваши функции символов и current_events возвращают только «фиктивные» объекты, которые, как вы знаете, являются правильными.

  3. Вы проверяете с помощью клиента REST (или с помощью более формального тестирования), что ответ работает правильно.

  4. Вы пишете свой ajax-код на стороне клиента и проверяете, что он работает с фиктивным выводом.

  5. Вы реорганизуете фиктивные вызовы объектов в функции, которые вызываютсами объекты (вы можете коротко проверить, возвращают ли они объекты так, как должны.

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

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