AppEngine,实体缺失?

时间:2014-04-09 22:06:11

标签: python google-app-engine

所以我有2个模型类:

class Profile(db.Model):
  """Profiles are merely lighter versions of Users. The are only used for the
  purpose of notification
  """
  created_at = db.DateTimeProperty(auto_now_add=True)
  created_by = None   # TODO User class
  name = db.StringProperty()
  email = db.EmailProperty()
  phone = db.PhoneNumberProperty()


class Notification(db.Model):
  LEVELS = {
      'INFO': 'INFO',
      'WARNING': 'WARNING',
      'CRITICAL': 'CRITICAL'
  }
  created_by = None   # TODO user class
  created_at = db.DateTimeProperty(auto_now_add=True)
  profile = db.ReferenceProperty(Profile, collection_name='notifications')
  level = db.StringProperty()

这就是我的JSONencoder的样子:

class JsonEncoder(json.JSONEncoder):
  def default(self, obj):
    if isinstance(obj, datetime.datetime):
      return obj.isoformat()
    elif isinstance(obj, Profile):
      return dict(key=obj.key().id_or_name(),
                  name=obj.name, email=obj.email, phone=obj.phone)
    elif isinstance(obj, Limits):
      return None
    else:
      return json.JSONEncoder.default(self, obj)

基本上,可以为配置文件分配通知,以便在通知触发时,将通知与该通知关联的所有配置文件。

在我的html中,我有一个允许用户创建通知的表单:

  <form action="{{ url_for('new_notification') }}" method=post>

    <!-- If disabled=true we won't send this in the post body -->
    Name:
    <input name='name' type='text' value='Select from above' disabled=true />
    <br/>

    <!-- if type=hidden html will still send this in post body -->
    <input name='key' type='hidden' value='Select from above' />

    Type:
    <select name='level'>
      {% for k,v in notification_cls.LEVELS.iteritems() %}
      <option value="{{ v }} ">{{ k }}</option>
      {% endfor %}
    </select>
    <br/>

    <input type="submit" value="Submit">
  </form>

但是,我发现在我的方法中发生了一些奇怪的事情来创建通知:

@app.route('/notifications/new/', methods=['GET', 'POST'])
def new_notification():
  """Displays the current notifications avaiable for each profiles
  """
  if request.method == 'GET':
    return render_template('new_notification.html',
                           notification_cls=Notification)
  else:
    profile_key_str = request.form.get('key', None)
    level = request.form.get('level', None)
    if not profile_key_str or not level:
      abort(404)

    profile_key = db.Key.from_path('Profile', profile_key_str)

    profile = Profile.get(profile_key)
    print profile     # This results in None??

    notification = Notification(parent=profile)   # Ancestor for strong consistency
    notification.profile = profile_key
    notification.level = level
    notification.put()
    return redirect(url_for('list_notifications'), code=302)

因此,用户可以在new_notifications页面上创建个人资料。之后,我的服务器将通过ajax将新创建的实体的密钥发送到包含该表单的同一页面。这将设置隐藏输入的值。

不知怎的,在我的new_notification方法中,Profile不存在!!!!我对AppEngine的“最终一致性”政策持怀疑态度,但我一直在等待30分钟,结果仍然是无。

任何想法我做错了什么?

编辑:

我忘了包含为我的JS调用JSONEncoder的方法

@app.route('/profiles/', methods=['GET'])
def ajax_list_profiles():
  def _dynatable_wrapper(profiles):
    return {'records': profiles,
            'queryRecordCount': len(profiles),
            'totalRecordCount': len(profiles)}
  name = request.args.get('queries[search]', None)
  if not name:
    profiles = db.Query(Profile).order('name').fetch(None)
    return json.dumps(_dynatable_wrapper(profiles), cls=JsonEncoder)
  else:
    profiles = db.Query(Profile).filter("name =", name).order('name').fetch(None)
    return json.dumps(_dynatable_wrapper(profiles), cls=JsonEncoder)

1 个答案:

答案 0 :(得分:0)

您可能希望使用int作为键路径,否则它会认为它是一个键名。