Google应用引擎ReferenceProperty关系

时间:2009-07-31 02:02:58

标签: python google-app-engine django-models model django-templates

我正在尝试使用ReferenceProperty获取我的模型,但没有大量的运气。我有3个级别:Group,Topic,然后是Pros和Cons。因为在一个小组中有许多主题,并且在每个主题内可能有许多优点和缺点。

我可以很好地存储新的群组,但我不知道如何在这些群组下存储主题。我想从一个页面链接到每个组下面的“新主题”链接,这会将它们转换为一个简单的形式(现在是1个字段)。显然,URL需要对组的id或类似内容进行某种引用。

以下是我的模特:

class Groups(db.Model):

    group_user = db.UserProperty()
    group_name = db.StringProperty(multiline=True)
    group_date = db.DateTimeProperty(auto_now_add=True)


class Topics(db.Model):

    topic_user = db.UserProperty()
    topic_name = db.StringProperty(multiline=True)
    topic_date = db.DateTimeProperty(auto_now_add=True)
    topic_group = db.ReferenceProperty(Groups, collection_name='topics')

class Pro(db.Model):

    pro_user = db.UserProperty()
    pro_content = db.StringProperty(multiline=True)
    pro_date = db.IntegerProperty(default=0)
    pro_topic = db.ReferenceProperty(Topics, collection_name='pros')    

class Con(db.Model):

    con_user = db.UserProperty()
    con_content = db.StringProperty(multiline=True)
    con_date = db.IntegerProperty(default=0)
    con_topic = db.ReferenceProperty(Topics, collection_name='cons')    

实际页面的一个功能我想显示组列表,然后在其主题下面:

class Summary(webapp.RequestHandler):
    def get(self):

        groups_query = Groups.all()
        groups = groups_query.fetch(1000)
        template_values = {

            'groups': groups,           
        }

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

最后是html:

<html>
  <body>
    <a href="/newgroup">New Group</a>
    <br>
    {% for group in groups %}

    <font size="24">{{ group.group_name|escape }}</font><br> by <b>{{ group.group_user }}</b> at <b>{{ group.group_date }}</b> {{ group.raw_id }}
    <br>
    <a href="/newtopic?id={{group.key.id}}" >New topice </a>
    <br>
    <blockquote>
        {{ topics.topics_name }}
    </blockquote>


    {% endfor %}
  </body>
</html>

4 个答案:

答案 0 :(得分:2)

有副作用的东西,例如改变商店(例如通过创建新对象)应该 NOT 是HTTP GET - GET应该基本上只做“读取”操作。这不是迂腐,它是HTTP语义的关键部分 - 浏览器,缓存,代理等,允许作为只读操作作用于GET(例如通过缓存结果而不是将请求传递给服务器,如果它们可以从缓存中满足。)

对于修改,使用HTTP谓词(如POST(最流行,主要是因为所有浏览器都能正确实现)或者用于专门操作PUT(创建新对象)或DELETE(删除对象)。我假设您将使用POST来支持各种浏览器。

要从浏览器获取POST,您需要使用Javascript wizardy或者使用method = post的普通旧表单 - 为了简单起见,我会假设后者。

如果你正在使用Django 1.0(现在支持app引擎),它有自己的机制来根据模型制作,验证和接受表单。其他框架有自己类似的高级图层。

如果你想避免“丰富”的框架,你必须通过HTML模板的手工模板实现,将它们(通过某种URL调度,例如在app.yaml中)引导到你的实现的处理程序def post(self):,从请求中获取数据,验证它,形成新对象,放置它,显示一些确认页面。

您不清楚该程序的哪些部分或部分内容?你的问题的标题专注于参考属性,但我不确定他们特别给你带来了什么问题 - 从你的问题文本看来,你似乎对它们有正确的解决方法。

编辑:OP现已在评论中澄清他的问题是如何制作类似:

"<a href="/newtopic?id={{group.key.id}}" >New topic </a>" 

的工作。有不止一种方法可以做到这一点。如果新主题URL由静态表单提供,则该表单的帖子“操作”的处理程序可以通过id=标题(臭名昭着但无法修复的错误拼写)返回到Referer:,但那有点笨重而脆弱。更好的方法是让一个处理程序提供newtopic URI,def get从请求中获取id=并将其插入到结果表单模板中 - 例如,在隐藏的输入字段中。让该表单的模板包含(在其他字段中):

<INPUT TYPE=hidden NAME=thegroupid VALUE={{ theid }}> </INPUT>

theid放在您呈现该模板的上下文中,并且请求中最终会获得接收表单的操作的def post

答案 1 :(得分:1)

只是回答其他人的问题,因为你可能已经想到了这一点:

class NewTopic(webapp.RequestHandler):
    def get(self):
      groupId = self.request.get('group')
      # either get the actual group object from the DB and initialize topic with topic_group=object as in 'Nick Johnson's answer, or do as follows
      topic = Topic()
      topic.name = self.request.get("topicname")
      topic.reference = groupId
      topic.put()

答案 2 :(得分:0)

谢谢你的回复。

是的我知道get vs post。我发布的课程只是为了实际打印所有的组()。

我遇到的问题是我不确定如何使用模型以某种分层方式保存数据,使用Groups&gt;主题&gt;优点/缺点。

抓取数据很简单,我正在使用:

class NewGroupSubmit(webapp.RequestHandler):
    def post(self):

        group = Groups()
        if users.get_current_user():
            group.group_user = users.get_current_user()     
        group.group_name = self.request.get('groupname')

        group.put()
        self.redirect('/summary')

我需要另一个功能来添加一个新主题,将其存储在该组中。因此,假设一个群体就是“汽车”;主题可能是“法拉利”,“保时捷”,“宝马”,然后是每个主题的优缺点。我意识到我有点模糊,但这是因为我对关系数据库很新,并且不太习惯于术语。

答案 3 :(得分:0)

我不太确定你遇到了什么问题。您列出的所有内容都很好 - ReferenceProperties是根据您对dscription的期望设置的。我能看到的唯一问题是,在你的模板中,你指的是一个变量“主题”,它没有在任何地方定义,你也没有在任何地方迭代一个组的主题。你可以这样做:

<html>
  <body>
    <a href="/newgroup">New Group</a>
    <br>
    {% for group in groups %}

    <font size="24">{{ group.group_name|escape }}</font><br> by <b>{{ group.group_user }}</b> at <b>{{ group.group_date }}</b> {{ group.raw_id }}
    <br>
    <a href="/newtopic?id={{group.key.id}}" >New topice </a>
    <br>
    Topics:
    <ul>
      {% for topic in group.topics %}
        <li>{{topic.topic_name}}</li>
      {% endfor %}
    </ul>
    {% endfor %}
  </body>
</html>

要创建新主题,只需使用构造函数,传入所需的参数:

mytopic = Topic(topic_name="foo", topic_group=somegroup)

这里,某个组应该是Group对象,或者是Group对象的键。