0

我遇到访问数据存储实体的问题。我是GAE和Python的新手,所以要善良。我一直在寻找来自在线教程和其他示例代码的代码,到现在为止这一直很顺利。GAE呈现“无”,但我可以在数据存储查看器中看到数据存储实体

最终,我希望能够剥离电子邮件附件,对文件进行一些简单的更改并与其他.kml文件(或更好的.kmz文件)合并(但是一次只能执行一项操作: )。

step1。是发送电子邮件到应用程序的appspotmail地址=完成:)

step2。 ...写入到db.model =我可以在仪表板/数据存储区查看器中看到实体在那里,因此没有问题=完成:)

step3。 - 呈现一个模板以显示最近收到的20封电子邮件。这个名单将动态更新..... :(Hmmmmm

反而会发生什么情况是,我看到index.html中呈现的所有变量none。可以或许点我在正确的方向?谢谢!

DAV-O

这里是yaml.app

application: racetracer 
version: 1 
runtime: python27 
api_version: 1 
threadsafe: false 

libraries:                  
- name: jinja2                 
    version: latest 

handlers: 
- url: /_ah/mail/.+ 
    script: handle_incoming_email.py 
    login: admin 

- url: /favicon.ico 
    static_files: images/favicon.ico 
    upload: images/favicon.ico 

- url: /static/css 
    static_dir: static/css 

- url: /static/html 
    static_dir: static/index.html 

- url: .* 
    script: main.app 

inbound_services: 
- mail 

这里是handle_incoming_email.py

import logging, email 
import cgi 
import datetime 
import os.path 
import os 

from os import path 
from google.appengine.ext import webapp 
from google.appengine.ext import db 
from google.appengine.ext.webapp.mail_handlers import InboundMailHandler 
from google.appengine.ext.webapp.util import run_wsgi_app 
from google.appengine.ext.webapp.template import render 
import jinja2 
import wsgiref.handlers 

from main import * 
from baseController import * 
from authController import * 

class Vault(db.Model): 
    #fromAddress= db.UserProperty() 
    fromAddress= db.StringProperty() 
    subject = db.StringProperty(multiline=True) 
    #date = db.DateTimeProperty(auto_now_add=True) 
    date = db.StringProperty(multiline=True) 
    name = db.StringProperty(multiline=True) 

class ProcessEmail(InboundMailHandler): 
    def receive(self, mailMessage): 
     logging.info("Email from: " + mailMessage.sender + " received ok") 
     logging.info("Email subject: " + mailMessage.subject) 
     logging.info("Email date: " + mailMessage.date) 

     fromAddress = mailMessage.sender 
     subject = mailMessage.subject 
     date = mailMessage.date 

     if not hasattr(mailMessage, 'attachments'): 
      logging.info("Oi, the email has no attachments") 
      # raise ProcessingFailedError('Email had no attached documents') 
     else: 
      logging.info("Email has %i attachment(s) " % len (mailMessage.attachments)) 

      for attach in mailMessage.attachments: 
       name = attach[0] #this is the file name 
       contents = str(attach[1]) #and this is the attached files contents 
       logging.info("Attachment name: " + name) 
       logging.info("Attachment contents: " + contents) 
       vault = Vault() 
       vault.fromAddress = fromAddress 
       vault.subject = subject 
       vault.date = date 
       vault.name = name 
       vault.contents = contents #.decode() EncodedPayload.decode() 
        vault.put()  

       #f = open("aardvark.txt", "r") 
       #blah = f.read(30); 
       #logging.info("the examined string is : " + blah) 
       #f.close() # Close opened file 

app = webapp.WSGIApplication([ 
    ProcessEmail.mapping() 
], debug=True) 

def main(): 
    run_wsgi_app(app) 

if __name__ == "__main__": 
    main() 

,这里是basecontroller.py

from authController import * 
from handle_incoming_email import * 
import logging 
import os 
import webapp2 
import jinja2 
import wsgiref.handlers 

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

TEMPLATE_DIR = os.path.join(os.path.dirname(__file__)) 
jinja_environment = \ 
    jinja2.Environment(loader=jinja2.FileSystemLoader(TEMPLATE_DIR)) 

class Vault(db.Model): 
    #fromAddress= db.UserProperty() 
    fromAddress= db.StringProperty() 
    subject = db.StringProperty(multiline=True) 
    #date = db.DateTimeProperty(auto_now_add=True) 
    date = db.StringProperty(multiline=True) 
    name = db.StringProperty(multiline=True) 

class MainPage(webapp2.RequestHandler):  
    def get(self): 
     logging.info("this is MainPage in baseController") 
     list = db.GqlQuery("SELECT * FROM Vault ORDER BY date DESC").fetch(10) 
     logging.info("this is in list: " + str(list)) 

     vault = Vault() 

     fromAddress = vault.fromAddress 
     subject = vault.subject 
     date = vault.date 
     name = vault.name 

     values = { 
       'fromAddress': fromAddress, 
      'subject': subject, 
      'date': date, 
      'name': name, 
      } 
     templ = jinja_environment.get_template('index.html') 
     self.response.out.write(templ.render(values))       

def main(): 
    wsgiref.handlers.CGIHandler().run(app) 

if __name__ == "__main__": 
    main() 

我在教程中读到呈现模板是一种优于只使用在的.py的HTML,但也许我在太多的文件碎下来?他们的逻辑是不同的人做前端和后端,所以现在就习惯。反正上面有意渲染的index.html是:

的index.html

{% extends "base.html" %} 
{% block title %} racetracer {% endblock %} 
{% block content %} 
<h1>Racetracer </h1> 
<h3>Files recently received :</h3> 
<br> 
     <table> 
     <tr> 
      <th>Email address:     </th> 
      <th>-----------      </th> 
      <th>Subject:      </th> 
      <th>Date Received:     </th> 
      <th>Attachment:      </th> 
     </tr>   
     <tr>     
      <td> {{ fromAddress }}    </td> 
      <td> ---------------    </td> 
      <td> {{ subject }}     </td> 
      <td> {{ date }}      </td> 
      <td> {{ name }}      </td> 
     <blockquote>{{ content|escape }}</blockquote>      
     </p> 
     </tr>        
    </tr>  
    </table>  
<br> 

<hr> 
<form action="/sign" method="post"> 
    <textarea name="content" rows="1" cols="20"></textarea> 
    <input type="submit" value="Submit (in index:)"> 
</form> 
{% endblock %} 

和base.html文件....

<html><head> 
<link type="text/css" rel="stylesheet" href="/static/css/main.css" /></head> 

<body> From the file base out in the racetracer folder<br> 
right now you are logged in as : 
    {% if user %} 
     {{ user.nickname }}! 
     [<a href="{{ logout }}"><b>sign out</b></a>] 
    {% else %} 
     anonymous, who are you? 
     [<a href="{{ login }}"><b>sign in</b></a>] 
    {% endif %} 
    {% block content %} 
    {% endblock %} 
</body></html> 

,这里是main.py

import os 
import webapp2 
from handle_incoming_email import * 
from baseController import * 
from authController import * 
from google.appengine.ext.webapp import template 

app = webapp2.WSGIApplication([ 
    ('/', MainPage), 
    #('/ProcessEmail', ProcessEmail), 
], debug=True) 

def main(): 
    wsgiref.handlers.CGIHandler().run(app) 

if __name__ == "__main__": 
    main() 

感谢您的帮助!这将非常感激。

+0

您应该将模型移动到单个文件中并将其导入到不同的处理程序中,因为您有2个独立的Vault实现,所以很容易引入各种错误。 – 2013-03-26 06:48:21

+0

好的,谢谢蒂姆。所以我会创建一个model.py文件,它只是由'class vault'组成,因为它是上面的,并且在需要时添加'from model.py import *',是的?不知道这会改变任何渲染问题,虽然??? – user2206361 2013-03-26 11:38:15

+0

是的,我没有解决你的实际问题,以通过:-)的很多代码,但复制类作为一个普遍的问题等待咬人:-) – 2013-03-26 12:28:35

回答

1

你得到None,因为它是None。您声明的是Vault对象,但不会为其分配任何值。作为GQL查询的结果,这些值将位于列表实体中。

vault = Vault() # This creates an empty object (assuming you aren't doing any dynamic init 

fromAddress = vault.fromAddress # Still empty.... 
subject = vault.subject 
date = vault.date 
name = vault.name 

此外,你不应该指定列表作为一个变种,因为这是保留给Py。

你想要做的是设置这样的:

my_list = YOUR GQL QUERY.fetch() 

# Create a formatted list 
values = [] 
for ml in my_list: 
    value = { 
      'fromAddress': ml.fromAddress, 
     'subject': ml.subject, 
     'date': ml.date, 
     'name': ml.name, 
     } 

    values.append(value) # You could just append the dictionary directly here, of course 

然后使用值列表中你模板PARAMS

** **更新相比

你GQL查询看起来不错到您的数据存储库模型。

首先,确保您已将'list'var更改为'my_list'。 接下来,如果你想看到打印为可读的字符串检索对象的内容,这 添加到您的模型:

def __unicode__(self): 
     return ('%s %s %s' % (self.key,self.fromAddress,self.subject)) # etc... for the vars you want printed with you print the object 

检查logging.info(my_list),并查看是否打印任何东西更具可读性。

如果没有,该列表上运行一个for循环并记录密钥和/或FROMADDRESS,因此:

for vault in my_list: 
    logging.info('the key = %s'%vault.key) 

如果不是返回任何东西,你的开发环境和运行中直接进入交互式控制台该查询:

from google.appengine.ext import db 
from *vault_file* import Vault 

my_list = db.GqlQuery("SELECT * FROM Vault ORDER BY date DESC").fetch(10) # run query 

for vault in my_list: 
    print vault.key 
    print vault.fromAddress 

让我知道这些测试离开你的位置,我会继续更新。

*更新#2 *

所以,现在你能确认你获得的数据存储值
要设置一个模板页面参数等于保管库列表中,这样:

params = dict(values=my_list) 
self.response.out.write(templ.render(params)) 

现在在您的页面上,您需要遍历列表以打印每个字典项目:

{% for vault in values %} 
    <tr> 
     <td>{{vault.fromAddress}}}</td> 
     etc... 
    </tr> 

{% endfor %} 

那工作?

+0

谢谢凯文。我按照你所说的改变了代码,但是html页面上没有任何东西(甚至没有来自以前的'none')。有一件事,我在'my_list = db.GqlQuery(“SELECT * FROM Vault ORDER BY date DESC”)中注意到了。在日志中这行产生'INFO 2013-03-26 22:32:24,828 baseController.py:36]这是在列表:[]'。这是否意味着Vault是正确写入的?你认为我应该在哪里看下一个?再次感谢。 Dav-o – user2206361 2013-03-26 22:36:57

+0

AND ....当我部署应用程序,然后看日志,我得到'这是在my_list:[,...等等。那么,如何最好地将它们转换为字符串? – user2206361 2013-03-26 22:52:53

+0

你的日志看起来像你的查询返回没有结果,所以让我们开始。你能证实你在数据存储中有什么吗? – kevin 2013-03-27 01:04:36

相关问题