سؤال

عند استخدام

from django.utils import simplejson

على كائنات الأنواع التي تستمد من db.Model إنه يلقي الاستثناءات. كيف تحايل على هذا؟

هل كانت مفيدة؟

المحلول 4

بما أنني لم أتمكن

from google.appengine.ext import db
from google.appengine.api.datastore_types import *

def dumpStr(obj):
    return "'" + obj + "'"

def dumps(obj):
    if isinstance(obj, str):
        return dumpStr(obj)
    elif obj == None:
        return None
    elif isinstance(obj, list):
        items = [];
        for item in obj:
            items.append(dumps(item))
        return '[' + ','.join(items) + ']'
    elif isinstance(obj, datetime.datetime):
        return "new Date('%s')" % obj.ctime()
    properties = [];
    for property in dir(obj):
        if property[0] != '_':
            value = obj.__getattribute__(property)
            valueClass = str(value.__class__)
            if not(('function' in valueClass) or ('built' in valueClass) or ('method' in valueClass)):
                value = dumps(value)
                if value != None:
                    properties.append("'" + property + "':" + value)
    if len(properties) == 0:
        return str(obj)
    else:
        return '{' + ','.join(properties) + '}'

نصائح أخرى

حسنًا - بيثون ليس رائعًا ، لذا فإن أي مساعدة سيكون موضع تقدير - لا تحتاج إلى كتابة محلل - هذا هو الحل:

أضف فئة utlity هذه http://code.google.com/p/google-app-engine-samples/source/browse/trunk/geochat/json.py؟r=55

 import datetime  
 import time 

 from google.appengine.api import users 
 from google.appengine.ext import db 

#this is a mod on the orinal file for some reason it includes its own simplejson files i have ref django!
 from django.utils import simplejson  

 class GqlEncoder(simplejson.JSONEncoder): 

   """Extends JSONEncoder to add support for GQL results and properties. 

   Adds support to simplejson JSONEncoders for GQL results and properties by 
   overriding JSONEncoder's default method. 
   """ 

   # TODO Improve coverage for all of App Engine's Property types. 

   def default(self, obj): 

     """Tests the input object, obj, to encode as JSON.""" 

     if hasattr(obj, '__json__'): 
       return getattr(obj, '__json__')() 

     if isinstance(obj, db.GqlQuery): 
       return list(obj) 

     elif isinstance(obj, db.Model): 
       properties = obj.properties().items() 
       output = {} 
       for field, value in properties: 
         output[field] = getattr(obj, field) 
       return output 

     elif isinstance(obj, datetime.datetime): 
       output = {} 
       fields = ['day', 'hour', 'microsecond', 'minute', 'month', 'second', 
           'year'] 
       methods = ['ctime', 'isocalendar', 'isoformat', 'isoweekday', 
           'timetuple'] 
       for field in fields: 
         output[field] = getattr(obj, field) 
       for method in methods: 
         output[method] = getattr(obj, method)() 
       output['epoch'] = time.mktime(obj.timetuple()) 
       return output 

     elif isinstance(obj, time.struct_time): 
       return list(obj) 

     elif isinstance(obj, users.User): 
       output = {} 
       methods = ['nickname', 'email', 'auth_domain'] 
       for method in methods: 
         output[method] = getattr(obj, method)() 
       return output 

     return simplejson.JSONEncoder.default(self, obj) 


 def encode(input): 
   """Encode an input GQL object as JSON 

     Args: 
       input: A GQL object or DB property. 

     Returns: 
       A JSON string based on the input object.  

     Raises: 
       TypeError: Typically occurs when an input object contains an unsupported 
         type. 
     """ 
   return GqlEncoder().encode(input)   

حفظ كما json.py

ليستخدم

import cgi
import os
import json 

from google.appengine.ext.webapp import template
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db


class Greeting(db.Model):
    author = db.UserProperty()
    content = db.StringProperty(multiline=True)
    date = db.DateTimeProperty(auto_now_add=True)

class MainPage(webapp.RequestHandler):
    def get(self):
        greetings_query = Greeting.all().order('-date')
        greetings = greetings_query.fetch(5)

        if users.get_current_user():
            url = users.create_logout_url(self.request.uri)
            url_linktext = 'Logout'
        else:
            url = users.create_login_url(self.request.uri)
            url_linktext = 'Login'

        template_values = {
            'greetings': greetings,
            'url': url,
            'url_linktext': url_linktext,
            }

        path = os.path.join(os.path.dirname(__file__), 'index.html')
        self.response.out.write(template.render(path, template_values))


class Guestbook(webapp.RequestHandler):
    def post(self):
        greeting = Greeting()

        if users.get_current_user():
            greeting.author = users.get_current_user()

        greeting.content = self.request.get('content')
        greeting.put()
        self.redirect('/')



#here i return my json feed - simple implementaion for example
class FeedHandler(webapp.RequestHandler):

  def get(self):
    """Retrieve a feed"""
    user = None

    greetings_query = Greeting.all().order('-date')
    rs= greetings_query.fetch(5)
#this is the part that calls the encoder - dosnt cause an exception
    data = json.encode(rs)



#roll out to browser -might need to check my headers etc
    self.response.headers['Content-Type'] = 'application/json; charset=utf-8'  
    self.response.out.write(data)




application = webapp.WSGIApplication(
                                       [
                                       ('/', MainPage),
                                       ('/sign',Guestbook),
                                       ('/feed',FeedHandler),
                                       ], debug=True
                                    )

def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()

هذه هي استجابة المتصفح:

{"المحتوى": "" ، "التاريخ": {"ctime": "السبت 23 يناير 02:40:22 2010" ، "الساعة" ": 22 ،" microsecond ": 434000 ،" isocalendar ": [2010 ، 3 ، 6] ، : 2010 ، "Epoch": 1264214422.0 ، "Isoformat": "2010-01-23T02: 40: 22.434000" ، "Day": 23 ، "Minute: 40} ، example.com "،" البريد الإلكتروني ":" test@example.com "،" auth_domain ":" gmail.com "}} ، {" content ":" "،" date ": {" ctime ": 01:12:43 2010 "،" ساعة ": 1 ،" IsoweEkday ": 6 ،" شهر ": 1 ،" ثانية ": 43 ،" microsecond ": 972000 ،" isocalendar ": [2010 ، 3 ، 6] ، "Timetuple": [2010 ، 1 ، 23 ، 1 ، 12 ، 43 ، 5 ، 23 ، -1] ، "Year": 2010 ، "Epoch": 1264209163.0 ، "Isoformat": "2010-01-23T01: 12: 43.972000 "،" اليوم ": 23 ،" دقيقة ": 12} ،" المؤلف ": {" لقب ":" test@example.com "،" البريد الإلكتروني ":" test@example.com "،" Auth_domain ":" gmail.com "}} ، {" content ":" test "،" date ": {" ctime ": الشهر ": 1 ،" الثاني ": 13 ،" microsecond ": 659000 ،" Ocalendar ": [2010 ، 3 ، 5] ،" Timetuple ": [2010 ، 1 ، 22 ، 22 ، 32 ، 13 ، 4 ، 22 ، -1] ،" Year ": 2010 ،" Epoch ": 1264199533.0 ،" Isoformat ":" 2010-01-22T22: 32: 13.659000 "،" Day ": 22 ،" Minute ": 32} ،" Author ": {" namname ":" test@example.com " example.com "،" auth_domain ":" gmail.com "}} ، {" content ":" "،" date ": {" ctime ":" Fri Jan 22 22:29:49 2010 "،" Hour " : 22 ، "isoweakday": 5 ، "شهر": 1 ، "ثانية": 49 ، "microsecond": 358000 ، "isocalendar": [2010 ، 3 ، 5] ، "Timetuple: [2010 ، 1 ، 22 ، 22 ، 29 ، 49 ، 4 ، 22 ، -1] ، "السنة": 2010 ، "Epoch": 1264199389.0 ، "isoformat": "2010-01-22T22: 29: 49.358000" ، "Day": "Minute" ": 29} ،" المؤلف ": {" namname ":" test@example.com "،" البريد الإلكتروني ":" test@example.com "،" auth_domain ":" gmail.com "}} ، {" المحتوى " : "آه إنه يعمل! r n" ، "التاريخ": {"ctime": "الجمعة 22 يناير 22:29:22 2010 ، ، "الثاني": 22 ، "microsecond": 995000 ، "isocalendar": [2010 ، 3 ، 5] ، "Timetuple": [2010 ، 22 ، 22 ، 29 ، 22 ، 4 ، 22 ، -1] ، "السنة": 2010 ، "Epoch": 1264199362.0 ، "Isoformat": " 2010-01-22T22: 29: 22.995000 "،" Day ": 22 ،" Minute ": 29} ،" Author ": {" namname ":" test@example.com "،" البريد الإلكتروني ":" Test@example. com "،" auth_domain ":" gmail.com "}}

المثال المقدم من Jader Dias يعمل بشكل جيد لقلقي بعد بعض twaeking. قم بإزالة طريقة التشفير لأنها تحتوي على مرجع دائري. يجب أن تبدو الفئة المعدلة مثل:

import datetime  
import time 

from google.appengine.api import users 
from google.appengine.ext import db 
from django.utils import simplejson  


class GqlEncoder(simplejson.JSONEncoder): 

    """Extends JSONEncoder to add support for GQL results and properties. 

    Adds support to simplejson JSONEncoders for GQL results and properties by 
    overriding JSONEncoder's default method. 
    """ 

    # TODO Improve coverage for all of App Engine's Property types. 

    def default(self, obj): 

        """Tests the input object, obj, to encode as JSON.""" 

        if hasattr(obj, '__json__'): 
            return getattr(obj, '__json__')() 

        if isinstance(obj, db.GqlQuery): 
            return list(obj) 

        elif isinstance(obj, db.Model): 
            properties = obj.properties().items() 
            output = {} 
            for field, value in properties: 
                output[field] = getattr(obj, field) 
            return output 

        elif isinstance(obj, datetime.datetime): 
            output = {} 
            fields = ['day', 'hour', 'microsecond', 'minute', 'month', 'second', 'year'] 
            methods = ['ctime', 'isocalendar', 'isoformat', 'isoweekday', 'timetuple'] 
            for field in fields: 
                output[field] = getattr(obj, field) 
            for method in methods: 
                output[method] = getattr(obj, method)() 
            output['epoch'] = time.mktime(obj.timetuple()) 
            return output

        elif isinstance(obj, datetime.date): 
            output = {} 
            fields = ['year', 'month', 'day'] 
            methods = ['ctime', 'isocalendar', 'isoformat', 'isoweekday', 'timetuple'] 
            for field in fields: 
                output[field] = getattr(obj, field) 
            for method in methods: 
                output[method] = getattr(obj, method)() 
            output['epoch'] = time.mktime(obj.timetuple()) 
            return output 

        elif isinstance(obj, time.struct_time): 
            return list(obj) 

        elif isinstance(obj, users.User): 
            output = {} 
            methods = ['nickname', 'email', 'auth_domain'] 
            for method in methods: 
                output[method] = getattr(obj, method)() 
            return output 

        return simplejson.JSONEncoder.default(self, obj) 

عندما قمت بحفظ هذه الفئة في ملف يسمى utils.py وعند الاقتضاء أقوم باستيراده باستخدام

import utils

ثم أدعو utils.gqlencoder (). التشفير (النتائج) ، على سبيل المثال:

query = User.all()
results = query.fetch(10)

self.response.headers['Content-Type'] = "text/plain" # Alt. application/json
self.response.out.write( utils.GqlEncoder().encode(results) )

يجب أن تبدو النتيجة شيئًا من هذا القبيل (لقد أضفت بعض الخلاصات من أجل تسهيل القراءة):

[
{"date": {"ctime": "Tue Feb 23 10:41:21 2010", "hour": 10, "isoweekday": 2, "month": 2, 
        "second": 21, "microsecond": 495535, "isocalendar": [2010, 8, 2], "timetuple": [2010, 2, 23, 10, 41, 21, 1, 54, -1], 
        "year": 2010, "epoch": 1266921681.0, "isoformat": "2010-02-23T10:41:21.495535", "day": 23, "minute": 41}, 
"claimed_id": "https:\/\/www.google.com\/accounts\/o8\/id?id=abcdefghijklmnopqrstuvxyz", 
"display_name": "Alfred E Neumann", 
"email": null, 
"full_name": "Alfred E Neumann"
}, 
{"date": {"ctime": "Tue Feb 23 11:00:54 2010", "hour": 11, "isoweekday": 2, "month": 2, 
        "second": 54, "microsecond": 805261, "isocalendar": [2010, 8, 2], "timetuple": [2010, 2, 23, 11, 0, 54, 1, 54, -1], 
        "year": 2010, "epoch": 1266922854.0, "isoformat": "2010-02-23T11:00:54.805261", "day": 23, "minute": 0}, 
"claimed_id": "http:\/\/openid.domain.net\/john", 
"display_name": "", 
"email": "jp@domain.net", 
"full_name": "John Parnefjord"
}
]

لا يمكن استخدام JSON لتسلسل أي شيء أكثر من الأنواع الأساسية مثل الديكتات والقوائم و ints/longs والسلاسل (هذا غير شامل). على سبيل المثال ، حتى هذه الأوامر البسيطة لا تعمل:

import json
json.dumps(object())

إذا كنت ترغب في إجراء تسلسل كائنات Django ، فيجب عليك الإشارة إلى وثائق Django حول التسلسل, ، والتي ستستخدم مكتباتها الخاصة ، لكنها تدعم JSON.

من ما يمكنني فهمه - وأنا جديد على Python - مع محرك تطبيق Google ، فإن العمل حوله هو تسلسل كائن النموذج إلى كائن Python dictioanry ثم استخدم JSON البسيط لتفريغه كسلسلة JSON - هذا لا معنى له بالنسبة لي - ربما يكون لدى شخص ما أن يعلم التسلسل إلى Ditionary (Pickel؟) أي مساعدة في هذا سيكون مساعدة! عدم الإعجاب بأن Google App Engine ليس لديه حل في ثنائية المليء بهذا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top