1

所以我在 python 中有以下代码 GAE 代码,它有点长,但基本上它允许用户发布到博客,然后将每个博客帖子保存到用户被重定向到的永久链接,并且用户可以永远重新链接到。永久链接 url 就是 blog/(博客文章 ID)。所以永久链接是通过重定向方法在 NewPost 处理程序中创建的(如果我错了,请纠正我),然后这些永久链接的列表存储在哪里?它可以以某种方式访问​​吗?因为我无法从视觉上看到它,所以这部分让我有点绊倒。

我从 Udacity.com 学到了所有这些代码,但他们并没有真正解释这一点,我可以让它工作,但不明白它是如何工作的。

import os
import re
from string import letters

import webapp2
import jinja2

from google.appengine.ext import db

template_dir = os.path.join(os.path.dirname(__file__), 'templates')
jinja_env = jinja2.Environment(loader = jinja2.FileSystemLoader(template_dir),
                               autoescape = True)

def render_str(template, **params):
    t = jinja_env.get_template(template)
    return t.render(params)

class BlogHandler(webapp2.RequestHandler):
    def write(self, *a, **kw):
        self.response.out.write(*a, **kw)

    def render_str(self, template, **params):
        return render_str(template, **params)

    def render(self, template, **kw):
        self.write(self.render_str(template, **kw))

def render_post(response, post):
    response.out.write('<b>' + post.subject + '</b><br>')
    response.out.write(post.content)

#front page
class MainPage(BlogHandler):
  def get(self):
      self.write('Hello, Udacity!')

def blog_key(name = 'default'):
    return db.Key.from_path('blogs', name)

#creates the database
class Post(db.Model):
    subject = db.StringProperty(required = True)
    content = db.TextProperty(required = True)
    created = db.DateTimeProperty(auto_now_add = True)
    last_modified = db.DateTimeProperty(auto_now = True)

    def render(self):
        self._render_text = self.content.replace('\n', '<br>')
        return render_str("post.html", p = self)

#front of blog with list of last 10 posts
class BlogFront(BlogHandler):
    def get(self):
        posts = db.GqlQuery("select * from Post order by created desc limit 10")
        self.render('front.html', posts = posts)

#displays the permalink page
class PostPage(BlogHandler):
    def get(self, post_id):
        key = db.Key.from_path('Post', int(post_id), parent=blog_key())
        post = db.get(key)

        if not post:
            self.error(404)
            return

        self.render("permalink.html", post = post)

#create a new post
class NewPost(BlogHandler):
    def get(self):
        self.render("newpost.html")

    def post(self):
        subject = self.request.get('subject')
        content = self.request.get('content')

        if subject and content:
            p = Post(parent = blog_key(), subject = subject, content = content)
            p.put()
            self.redirect('/blog/%s' % str(p.key().id()))
        else:
            error = "subject and content, please!"
            self.render("newpost.html", subject=subject, content=content, error=error)


app = webapp2.WSGIApplication([('/', MainPage),
                               ('/unit2/welcome', Welcome),
                               ('/blog/?', BlogFront),
                               ('/blog/([0-9]+)', PostPage),
                               ('/blog/newpost', NewPost),
                               ],
                              debug=True)

更新:

是否可以通过以下方式更改代码以使其对搜索引擎更加友好:

class NewPost(BlogHandler):
    def get(self):
        self.render("newpost.html")

    def post(self):
        subject = self.request.get('subject')
        content = self.request.get('content')

        if subject and content:
            p = Post(parent = blog_key(), subject = subject, content = content)
            p.put()
            #the change is in the following line:
            self.redirect('/blog/%s/%s' % (str(p.key().id(), str(p.subject)))
        else:
            error = "subject and content, please!"
            self.render("newpost.html", subject=subject, content=content, error=error)

最后更新:

我使用以下代码解决了使其对搜索引擎更友好的问题:

 def post(self):
            subject = self.request.get('subject')
            content = self.request.get('content')

        if subject and content:
            p = Post(parent = blog_key(), subject = subject, content = content)
            p.put()
            subject = p.subject
            subject = subject.replace(' ', '25fdsa67ggggsd5')
            subject = ''.join(e for e in subject if e.isalnum())
            subject = subject.replace('25fdsa67ggggsd5', '-')
            subject = subject.lower()
            self.redirect('/blog/%s/%s' % (str(p.key().id(), str(subject)))
        else:
            error = "subject and content, please!"
            self.render("newpost.html", subject=subject, content=content, error=error)
4

1 回答 1

3

The ID of the blog post is all that is needed to retrieve it front the datastore, so there is no need for a mapping of any kind. A request comes in with the permalink URL, the ID is extracted from the URL, the post is retrieved from the datastore using the ID, the blog post is rendered.

It is a simple and effective strategy, but one area where it falls flat is search engine optimization. Most search engines would prefer a URL that has words in it rather than just a string of numbers and characters.

This is commonly called slugging, and it would require you to provide a mapping between the ID and a string. Several years ago, I wrote a mixin class that provided easy slugging for AppEngine/Python programs: sluggable-mixin. It should still work.

于 2012-06-20T18:41:39.210 回答