Flask post url不会重定向动态链接

时间:2015-07-21 19:26:42

标签: python flask

我目前在让我的教程瓶子在博客文章上显示动态链接时遇到问题。我想要的动态链接是      http://localhost:8000/blog/hello

但我得到了这个乱码链接 http://localhost:8000/%3Cbound%20method%20Post.url%20of%20%3C__main__.Post%20object%20at%200x7f04ddd9dd50%3E%3E

import os
import sys

import collections
from flask import Flask, render_template, url_for, abort, request 
from  flask.ext.frozen import Freezer
from werkzeug import cached_property
from werkzeug.contrib.atom import AtomFeed
import markdown
import yaml
from string import strip

POSTS_FILE_EXTENSION = '.md'

class SortedDict(collections.MutableMapping):
    def __init__(self, items= None, key=None, reverse=False):
        self._items = {} #python dict
        self._keys =[] #python list
        if key:
            self._key_fn = lambda k: key(self._items[k])
        else:
            self._key_fn = lambda k: self._items[k]
        self._reverse = reverse

        if items is not None:
            self.update(items)

    #abstract base class
    def __getitem__(self, key):
        return self._items[key]

    def __setitem__(self, key, value):
        self._items[key]= value
        if key not in self._keys:
            self._keys.append(key)
            self._keys.sort(key= self._key_fn, reverse= self._reverse)


    def __delitem__(self, key):
        self._items.pop(key)
        self._keys.remove(key)

    def __len__(self):
        return len(self._keys)

    def __iter__(self):
        for key in self._keys:
            yield key
    def __repr__(self):
        return '%s(%s)' % (self.__class__.__name__, self._items)

class Blog(object):
    def __init__(self, app, root_dir='',file_ext=POSTS_FILE_EXTENSION):
        self.root_dir = root_dir
        self.file_ext = file_ext
        self._app =app  #_ for private and internal
        self._cache = SortedDict(key = lambda p: p.date, reverse= True)
        self._initialize_cache()

    @property
    def posts(self):
        return self._cache.values()

    def get_post_or_404(self, path):
        """ Returns the Post object for the given path or raises a NotFound exception"""
        try:
            return self._cache[path]
        except KeyError:
            abort(404)

    def _initialize_cache(self):
        """walks the root directory and adds all posts to the cache """
        for (root, dirpaths, filepaths)  in os.walk(self.root_dir):
            for filepath in filepaths:
                filename, ext = os.path.splitext(filepath)
                if ext == self.file_ext:
                    path = os.path.join(root, filepath).replace(self.root_dir,'')
                    post = Post(path, root_dir = self.root_dir)
                    self._cache[post.urlpath] = post


class Post(object):
    def __init__(self, path, root_dir=''):
        self.urlpath = os.path.splitext(path.strip('/'))[0]
        self.filepath = os.path.join(root_dir, path.strip('/'))
        self._initialize_metadata()

    @cached_property
    def html(self):
        with open(self.filepath, 'r') as fin:
            content = fin.read().split('\n\n',1)[1].strip()
        return markdown.markdown(content)


    def url(self,_external= False):
        return url_for('post',path=self.urlpath, _external=_external)

    def _initialize_metadata(self):
        content = ''
        with open(self.filepath, 'r') as fin:
            for  line in fin:
                if not line.strip():
                    break
                content += line
        self.__dict__.update(yaml.load(content))

app =  Flask(__name__)
blog = Blog(app, root_dir= 'posts')
freezer = Freezer(app)

@app.template_filter('date')
def format_date(value, format = '%B %d, %Y'):
    from datetime import date, datetime, time
    return value.strftime(format)



@app.route('/')
def index():
    return render_template('index.html', posts= blog.posts)


@app.route('/blog/<path:path>/')
def post(path):
    #import ipdb; ipdb.set_trace()
    #import pdb; pdb.set_trace()
    #path = os.path.join('posts', path + POSTS_FILE_EXTENSION)
    #post = Post(path)
    post = blog.get_post_or_404(path)
    #post = Post(path + POSTS_FILE_EXTENSION, root_dir = 'posts')
    return render_template('post.html', post=post)

@app.route('/feed.atom')
def feed():
    feed = AtomFeed('Recent Articles',
                    feed_url=request.url,
                    url=request.url_root)
    posts = blog.posts[:10]
    title = lambda p: '%s: %s' %(p.title, p.subtitle) if hasattr(p, 'subtitle') else p.title
    for post in posts:
        feed.add(title(post),
                 unicode(post.html),
                 content_type='html',
                 author='Mancube',
                 url=post.url(_external= True),
                 updated=post.date,
                 published=post.date)
    return feed.get_response()


if  __name__ == '__main__':
    if len(sys.argv) > 1 and sys.argv[1] =='build':
        freezer.freeze()
    else:
        post_files = [post.filepath for post in blog.posts]
        app.run(port=8000, debug=True, extra_files = post_files)

我的index.html:

{% extends "base.html" %}
{% block head %}
    <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/index.css') }}">
{% endblock head %}

{% block content %}
    <div id="header">
        <h1>My awesome blog</h1>
    </div>

    <div id="posts">
    {% for  post in  posts %}
        <div class="post">
        <span class="post-date">{{ post.date|date }}</span>
        <a href="{{ post.url }}" class="post-title">
            {{ post.title}}{% if post.subtitle %}: {{ post.subtitle }} {% endif %}
        </a>
        </div>
    {% endfor %}

     </div>
{% endblock content %}

我对Flask很新,我希望有人可以帮助我。

1 个答案:

答案 0 :(得分:0)

href="{{ post.url }}"

这是一个函数,你需要用“post.url()”调用它。