2010-02-12 53 views
33

Tôi muốn sử dụng simplejson để tuần tự hóa mô hình Django. Trình serializer của Django không hỗ trợ từ điển ... và simplejson không hỗ trợ Django Querysets. Đây là một câu hỏi hóc búa.JSON Nối tiếp mô hình Django với simplejson

Trong mô hình có các nhà tài trợ có khóa ngoại để tài trợ cấp, tôi đang cố gắng nhóm tất cả các nhà tài trợ thuộc về một cấp nhà tài trợ nhất định với nhau. Dưới đây là đoạn code mà tạo ra danh sách:

from django.shortcuts import get_list_or_404 
from special_event.models import Sponsor, SponsorLevel 

sponsor_dict = {} 

roadie_sponsors = get_list_or_404(Sponsor, level__category = SponsorLevel.ROADIE_CHOICE) 

for item in roadie_sponsors: 
    try: 
     sponsor_dict[item.level.name].append(item) 
    except KeyError: 
     sponsor_dict[item.level.name] = [item] 

Đây là những gì sponsor_dict trông giống như khi nó đã được "làm"

{ 
    'Fan': [<Sponsor: Fan Sponsor>], 
    'VIP': [<Sponsor: VIP Sponsor>], 
    'Groupie': [<Sponsor: Groupie Sponsor>], 
    'Silver': [<Sponsor: Silver Sponsor>], 
    'Bronze': [<Sponsor: Another Bronze Sponsor>, <Sponsor: Bronze Sponsor>] 
} 

Tôi chỉ thêm một nhà tài trợ ở mỗi cấp, ngoại trừ đồng, chỉ để hiển thị nó như thế nào công trinh. Tất cả những gì tôi muốn làm là lấy nó "tất cả" vào JSON để jQuery có thể giải thích nó một cách dễ dàng. Các serializers khác của Django (như XML hay YAML) có thực hiện được điều này không? Tôi có thể "mở rộng" Django JSON Serializer để xử lý các từ điển hoặc "mở rộng" simplejson để xử lý các đối tượng Django QuerySet không?

Trả lời

39

Tôi sẽ mở rộng simplejson. Về cơ bản, bạn muốn cắm vào tuần tự hóa của django khi bộ mã hóa JSON gặp QuerySet. Bạn có thể sử dụng một cái gì đó như:

from json import dumps, loads, JSONEncoder 

from django.core.serializers import serialize 
from django.db.models.query import QuerySet 
from django.utils.functional import curry 

class DjangoJSONEncoder(JSONEncoder): 
    def default(self, obj): 
     if isinstance(obj, QuerySet): 
      # `default` must return a python serializable 
      # structure, the easiest way is to load the JSON 
      # string produced by `serialize` and return it 
      return loads(serialize('json', obj)) 
     return JSONEncoder.default(self,obj) 

# partial function, we can now use dumps(my_dict) instead 
# of dumps(my_dict, cls=DjangoJSONEncoder) 
dumps = curry(dumps, cls=DjangoJSONEncoder) 

Để biết thêm thông tin về phương thức default, hãy xem simplejson documentation. Đặt nó trong một mô-đun python, sau đó nhập dumps và bạn tốt để đi. Nhưng lưu ý rằng chức năng này sẽ chỉ giúp bạn serializing QuerySet trường hợp, không phải trực tiếp Model trường hợp.

+1

này là rất thông minh – babonk

10

dựa trên câu trả lời của Clement, tôi đã làm điều này để đưa mô hình vào JSON.

def toJSON(obj): 
    if isinstance(obj, QuerySet): 
     return simplejson.dumps(obj, cls=DjangoJSONEncoder) 
    if isinstance(obj, models.Model): 
     #do the same as above by making it a queryset first 
     set_obj = [obj] 
     set_str = simplejson.dumps(simplejson.loads(serialize('json', set_obj))) 
     #eliminate brackets in the beginning and the end 
     str_obj = set_str[1:len(set_str)-2] 
    return str_obj 
+0

Nếu bạn có một câu hỏi mà bạn cần nhấp vào nút 'hỏi câu hỏi' tại trên cùng bên phải. Biểu mẫu 'Câu trả lời của bạn' được sử dụng để đăng câu trả lời. – Pickels

+13

Lời xin lỗi của tôi. Tôi chỉ có ý định khen ngợi chủ đề này, vì câu trả lời chính làm cho chú ý rằng nó không thể tuần tự hóa các đối tượng. Mục tiêu này được thực hiện, vì mã này hoạt động. Câu hỏi của tôi về việc đó là một ý tưởng tốt hay một ý tưởng xấu có nghĩa là mời thảo luận về tích hợp tốt hơn, và chắc chắn không phải ai đã khinh miệt – jcage

13

Một cách thực sự linh hoạt để serialize nhất cấu trúc trong django là sử dụng lớp serializer tìm thấy here

+1

Chỉ cần thực hiện điều này. Thật rực rỡ! Kịch bản này xứng đáng được công nhận nhiều hơn. – Glycerine

+1

+1 - Điều này cũng làm việc rất tốt cho tôi. – RyanBrady

+0

Đây là một giải pháp rất đơn giản và thích nghi. – stormlifter

Các vấn đề liên quan