2011-07-06 49 views
15

Tôi đang cố sử dụng tính năng ValuesQuerySet trong Django để giới hạn số trường được trả lại từ truy vấn chỉ cho những trường tôi cần. Tôi muốn serialize dữ liệu này thiết lập một đối tượng JSON Tuy nhiên, Django giữ ném một lỗi. Dưới đây tôi đã bao gồm mã của tôi và lỗi tôi nhận được:Chuyển đổi một django ValuesQuerySet thành đối tượng json

objectList = ConventionCard.objects.values('fileName','id').filter(ownerUser = user) 
data = serializers.serialize('json', objectList) 
return HttpResponse(data, mimetype='application/javascript') 

Các Lỗi:

Exception Type:  AttributeError 
Exception Value: 'dict' object has no attribute '_meta' 
Exception Location:  C:\Python27\lib\site-packages\django\core\serializers\base.py in serialize, line 41 

Cảm ơn!

+0

Tại sao bạn sử dụng 'giá trị()'? Điều đó làm cho các đối tượng 'dict' không thể được tuần tự hóa một cách dễ dàng. –

+1

Tôi không muốn toàn bộ đối tượng của mình. Tôi chỉ muốn hai trường. Giá trị dường như là cách để làm điều này. Có cách nào tốt hơn? –

+0

Vì 'giá trị' không hoạt động, nói rằng" dường như là cách để làm điều này "không thể đúng. Nếu bạn muốn chỉ có hai trường, xin vui lòng ** cập nhật ** câu hỏi nói rằng rất, rất rõ ràng. Nó không rõ ràng trong câu hỏi. –

Trả lời

12

Hãy thử subsetting the fields trong giá trị của bạn danh sách thông qua các phương pháp serialize sử dụng một QuerySet thay vì:

from django.core import serializers 
objectQuerySet = ConventionCard.objects.filter(ownerUser = user) 
data = serializers.serialize('json', objectQuerySet, fields=('fileName','id')) 
+0

Điều này làm việc như một say mê. Cảm ơn bạn! –

+14

Không lý tưởng vì truy vấn đang kéo tất cả dữ liệu cột ra khi nó chỉ cần hai trường. – Aaron

+0

khi tôi đang thử điều này, tôi nhận thấy rằng, tùy chọn serializers.serialize 'fields', không chọn cột/trường của mô hình liên quan. Ai cũng phải đối mặt với nhau? –

30

Cast ValuesQuerySet vào một danh sách đầu tiên:

query_set = ConventionCard.objects.values('fileName','id').filter(ownerUser = user) 

list(query_set) 

Loại bỏ các values gọi theo đề nghị của ars nguyên nhân người quản lý để kéo tất cả các cột từ bảng, thay vì chỉ có hai cột bạn cần.

+3

Câu trả lời sáng chói. Hoạt động đẹp mắt. –

+0

Độ sâu đệ quy tối đa vượt quá khi gọi một đối tượng Python ... –

+0

Nó không hoạt động trong môi trường của tôi (Python 3.4, Django 1.8.3). –

1

Chỉ cần thêm một vài chi tiết tôi đã tìm thấy:

Khi tôi cố gắng @ars vị trả lời xác định các lĩnh vực, như:

s_logs = serializers.serialize("json", logs, fields=('user', 'action', 'time')) 

tôi có được điều này:

[{"pk": 520, "model": "audit.auditlog", "fields": {"user": 3, "action": "create", "time":"2012-12-16T12:13:45.540"}}, ... ] 

nào không phải là một serialization đơn giản của các giá trị như tôi muốn nó. Vì vậy, tôi đã thử giải pháp được đề xuất bởi @Aaron, chuyển đổi các giá trịqueryset thành danh sách, không hoạt động lần đầu tiên vì bộ mã hóa mặc định không thể xử lý các đối tượng nổi hoặc ngày giờ.

Vì vậy, tôi sử dụng @Aaron giải pháp nhưng bằng cách sử dụng mã hóa JSON được sử dụng bởi serializer django của (DjangoJSONEncoder) bằng cách đi qua nó như là một kwarg để simplejson.dumps(), như thế này:

s_logs = list(logs.values('user', 'ip', 'object_name', 'object_type', 'action', 'time')) 

return HttpResponse(simplejson.dumps(s_logs, cls=DjangoJSONEncoder), mimetype='application/javascript') 
+0

Nếu bạn đang sử dụng simplejson> 2.1, hãy xem vấn đề này: https://github.com/simplejson/simplejson/issues/37 Cho vấn đề đó, người ta có thể phải phân lớp 'simplejson.JSONEncoder' thay vì 'json.JSONEncoder' – defbyte

6

tôi tiếp tục để có được một "' đối tượng dict 'không có lỗi thuộc tính' _meta '"khi sử dụng phương thức list() ở trên. Tuy nhiên, tôi đã tìm thấy this snippet mẹo đó

def ValuesQuerySetToDict(vqs): 
    return [item for item in vqs] 

# Usage 
data=MyModel.objects.values('id','title','...','...') 
data_dict = ValuesQuerySetToDict(data) 
data_json = simplejson.dumps(data_dict) 
+0

Nó hoạt động, Cảm ơn! –

+0

Mô-đun 'simplejson' được [xóa] (https://docs.djangoproject.com/en/1.7/releases/1.5/#django-utils-simplejson) trong Django 1.5. Cách khác là chỉ đơn giản là 'nhập json' và sau đó sử dụng' json.dumps (data_dict) 'và câu trả lời là như mong đợi. –

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