Модели Django не являются сериализуемыми ajax

У меня есть простой взгляд, который я использую для экспериментов с AJAX.

def get_shifts_for_day(request,year,month,day):

    data= dict()
    data['d'] =year
    data['e'] = month
    data['x'] = User.objects.all()[2]

    return HttpResponse(simplejson.dumps(data), mimetype='application/javascript')

Это возвращает следующее:

TypeError at /sched/shifts/2009/11/9/

<User: someguy> is not JSON serializable

Если я вывожу строку данных ['x'], чтобы я не ссылался на какие-либо модели, она работает и возвращает это:

{"e": "11", "d": "2009"}

Почему simplejson не может проанализировать мою одну из стандартных моделей django? Я получаю то же поведение с любой моделью, которую я использую.

Ответ 1

Вам просто нужно добавить в свой вызов .dumps аргумент default=encode_myway, чтобы simplejson знал, что делать, когда вы передаете ему данные, типы которых он не знает, - ответ на ваш вопрос "почему", вопрос, конечно, в том, что вы не сказали бедным simplejson, что делать с одним из экземпляров ваших моделей.

И, конечно, вам нужно написать encode_myway для предоставления данных, кодируемых JSON, например:

def encode_myway(obj):
  if isinstance(obj, User):
    return [obj.username,
            obj.firstname,
            obj.lastname,
            obj.email]
    # and/or whatever else
  elif isinstance(obj, OtherModel):
    return [] # whatever
  elif ...
  else:
    raise TypeError(repr(obj) + " is not JSON serializable")

В принципе, JSON знает о ОЧЕНЬ элементарных типах данных (строки, ints и float, сгруппированные в dicts и списки) - это ВАША ответственность как программист приложений, чтобы соответствовать всем остальным в/из таких элементарных типов данных, а в simplejson, который обычно выполняется через функцию, переданную в default= в dump или dumps времени.

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