Domanda

So I have the following code GAE code in python and it is a little long but basically it allows a user to post to a blog and then saves each blog post to a permalink which the user is redirected to and the user can relink to forever. The permalink url is just blog/(the blog post ID). So the permalink is being created in the NewPost handler by the redirect method (correct me if I am wrong) and and then where is the list of these permalinks being stored? Is it accessible somehow? Because I cannot see it visually this part is tripping me up a little.

I learned all this code from Udacity.com but they didn't really explain this point and I can get it to work but don't understand how it is working.

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:

Would it be possible to change the code in the following way to make it a little more search engine 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)

FINAL UPDATE:

I solved the problem of making it more search engine friendly with the following bit of code:

 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)
È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top