2013-05-28 13 views
55

Tôi có mã sau để tuần tự hóa bộ truy vấn;<Đối tượng Django> không phải là JSON có thể nối tiếp

def render_to_response(self, context, **response_kwargs): 

    return HttpResponse(json.simplejson.dumps(list(self.get_queryset())), 
         mimetype="application/json") 

Và sau đây là của tôi get_querset()

[{'product': <Product: hederello()>, u'_id': u'9802', u'_source': {u'code': u'23981', u'facilities': [{u'facility': {u'name': {u'fr': u'G\xe9n\xe9ral', u'en': u'General'}, u'value': {u'fr': [u'bar', u'r\xe9ception ouverte 24h/24', u'chambres non-fumeurs', u'chambres familiales',.........]}] 

nào tôi cần phải serialize. Nhưng nó nói không thể tuần tự hóa <Product: hederello()>. Bởi vì danh sách bao gồm cả các đối tượng django và dicts. Bất kỳ ý tưởng?

Trả lời

65

simplejsonjson không hoạt động tốt với các đối tượng django.

Django tích hợp trong serializers chỉ có thể serialize queryset điền với các đối tượng django:

data = serializers.serialize('json', self.get_queryset()) 
return HttpResponse(data, content_type="application/json") 

Trong trường hợp của bạn, self.get_queryset() chứa một sự pha trộn của các đối tượng django và dicts bên trong.

Một lựa chọn là để thoát khỏi trường hợp mô hình trong self.get_queryset() và thay thế chúng với dicts sử dụng model_to_dict:

from django.forms.models import model_to_dict 

data = self.get_queryset() 

for item in data: 
    item['product'] = model_to_dict(item['product']) 

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

Hy vọng rằng sẽ giúp.

+0

Bây giờ nhận được lỗi -> 'đối tượng 'NoneType' không có thuộc tính 'concrete_model'' .. Và sử dụng Django 1.4+ – tunaktunak

+0

Tôi đã chỉnh sửa câu trả lời. Xin vui lòng xem nếu nó giúp. – alecxe

+2

Khi mô hình có trường ngày giờ, nó không hoạt động. – ax003d

5

Trước tiên, tôi đã thêm phương thức to_dict vào mô hình của mình;

def to_dict(self): 
    return {"name": self.woo, "title": self.foo} 

Sau đó, tôi có điều này;

class DjangoJSONEncoder(JSONEncoder): 

    def default(self, obj): 
     if isinstance(obj, models.Model): 
      return obj.to_dict() 
     return JSONEncoder.default(self, obj) 


dumps = curry(dumps, cls=DjangoJSONEncoder) 

và sử dụng lần cuối lớp này để sắp xếp lại bộ truy vấn của tôi.

def render_to_response(self, context, **response_kwargs): 
    return HttpResponse(dumps(self.get_queryset())) 

này hoạt động khá tốt

12

tôi thấy rằng điều này có thể được thực hiện khá đơn giản bằng cách sử dụng ".values" phương pháp, mà cũng là cấp cho tên lĩnh vực:

result_list = list(my_queryset.values('first_named_field', 'second_named_field')) 
return HttpResponse(json.dumps(result_list)) 

'danh sách' phải được sử dụng để nhận dữ liệu dưới dạng có thể lặp lại, vì loại "giá trị queryset" chỉ là một dict nếu được chọn là có thể lặp lại.

Tài liệu: https://docs.djangoproject.com/en/1.7/ref/models/querysets/#values

+0

Điều này làm việc tốt cho tôi.Mặc dù thông báo lỗi cho thấy tất cả đều nằm trong một danh sách lớn, nhưng 'list()' vẫn còn cần thiết. – trpt4him

+0

Giải pháp đơn giản và tốt nhất – Timur

3

Từ phiên bản 1.9 dễ dàng hơn và cách chính thức nhận json

from django.http import JsonResponse 
from django.forms.models import model_to_dict 


return JsonResponse( model_to_dict(modelinstance)) 
11

Cách đơn giản nhất là sử dụng một JsonResponse.

Đối với một queryset, bạn phải vượt qua một danh sách các các values cho queryset rằng, giống như vậy:

from django.http import JsonResponse 

queryset = YourModel.objects.filter(some__filter="some value").values() 
return JsonResponse({"models_to_return": list(queryset)})