Я тяну волосы за это. Я разрабатываю веб-приложение в 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
, но фактический контент не доставляется.