1

所以我在Python中有以下代碼GAE代碼,它有點長,但基本上它允許用戶發佈到博客,然後將每個博客帖子保存到用戶重定向到的永久鏈接,並且用戶可以重新鏈接到永遠。永久鏈接只是博客/(博客帖子ID)。因此,通過重定向方法在NewPost處理程序中創建永久鏈接(糾正我,如果我錯了),然後在哪裏存儲這些永久鏈接的列表?以某種方式訪問​​?因爲我看不見它,所以這個部分讓我有點絆倒。GAE商店永久鏈接在哪裏?

我從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) 

UPDATE:

是否可以更改代碼以下列方式,使其多了幾分搜索引擎friendy:

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) 
+1

沒有鏈接存儲在任何地方;只有一個「/ blog /」處理程序,後面跟着一個數字,用該ID顯示帖子。 – geoffspear

+0

沒關係,但以迂迴的方式將ID存儲在數據庫中,以便信息來自 – clifgray

+0

ID實際上並未存儲在數據庫中,本身;它是Key的一部分,不是一個單獨的值。 – geoffspear

回答

3

博客帖子的ID是在數據存儲區前檢索它所需的全部內容,因此不需要任何類型的映射。請求包含永久鏈接URL,ID從URL中提取,使用ID從數據存儲中檢索帖子,呈現博客文章。

這是一個簡單而有效的策略,但其中一個平坦的地方是搜索引擎優化。大多數搜索引擎會選擇一個包含單詞的網址,而不僅僅是一串數字和字符。

這通常被稱爲重擊,它會要求您提供ID和字符串之間的映射。幾年前,我編寫了一個mixin類,爲AppEngine/Python程序提供了輕鬆的段落:sluggable-mixin。它應該仍然有效。

+0

好的真棒。你知道是否知道如果檢索標題並在URL中使用該標題是否有效,或者只是沒有重複,可以使用標題/標識。 – clifgray

+0

對不起,但我真的不明白你的問題。 –

+0

我剛剛更新了我正在談論的代碼。 – clifgray