为博客创建存档列表

时间:2014-04-28 14:50:27

标签: python flask sqlalchemy jinja2

我尝试使用SQLAlchemy,Flask和Jinja创建一个包含计数的存档列表,如下所示。我不想展示没有帖子的月份。我无法弄清楚如何在字典中获得每个年份,月份和数量。

 2012 (11)
 - January (3)
 - February (5)
 - April (3)
 2013 (14)
 - April (2)
 - May (8)
 - June (2)
 - December
 2014 (13)
 - January (3)
 - February (8)
 - March (2)

模型

class Post(db.Model):
    ''' Returns the Post table.

   '''
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(80))
    url = db.Column(db.String(120), unique=True)
    body = db.Column(db.Text)
    create_date = db.Column(db.DateTime)
    pub_date = db.Column(db.DateTime)
    pub_status = db.Column(db.Text(80))
    author_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    topic_id = db.Column(db.Integer, db.ForeignKey('topic.id'))

    # relationships
    # one-to-many
    author = db.relationship('User', backref=db.backref('post', lazy='dynamic'))
    topic = db.relationship('Topic', backref=db.backref('post', lazy='dynamic'))

    # many-to-many
    tags = db.relationship('Tag', secondary=posts_tags, backref='posts', lazy='dynamic')

更新

此代码创建字典,但不确定如何添加计数。有任何想法吗?有更好的方法吗?

视图

# custom filter converts month number to "January", etc.
@app.template_filter('month_number')
def month_name(month_number):
    return calendar.month_name[month_number]

@app.route('/archive')
def display_archive():
    p = db.session.query(Post.pub_date).all()
    d = defaultdict(set) # removes the duplicate months by putting into sets.
    n = {}
    for i in p:
        d[i.pub_date.year].add(i.pub_date.month)
        d.items()

# first part returns eliminates dup months by making sets, needs sorting.
# defaultdict(<type 'set'>, {2012: set([1, 2, 4]),\
# 2013: set([4, 12, 5, 6]), 2014: set([1, 2, 3])})

for key, value in d.iteritems() :
        a = value
        a = list(a) #convert sets to list.
        a.sort()  # soft the list.
        n[key] = a

    return render_template('archive.html', d=d, n=n)

# convert to list for easy sorting.
#{2012: [1, 2, 4], 2013: [4, 5, 6, 12], 2014: [1, 2, 3]}

jinja2模板

    <dl>
    {% for key, value in n.iteritems() %}
        <dt>{{ key }}</dt>

        {% for v in value %}
           <dd><a href="/{{ key }}/{{ v }}">{{ v|month_number }}</a></dd>
        {% endfor %}
    {% endfor %}
    </dl>

Again, it works... but not sure how to add the counts.  It will have to be done before the defaultdict function I assume.

1 个答案:

答案 0 :(得分:0)

<强>解 这是最初在答案中发布的解决方案。

@app.route('/archive')
def display_archive():
    p = db.session.query(Post.pub_date).all()
    d = defaultdict(list)
    for i in p:
        d[i.pub_date.year].append(i.pub_date.month)

    # add the monthly counts by counting the instances of month number.
    adict = {}
    for k, v  in d.items():
        adict[k] = Counter(v)

    bdict = {}
    # add the monthly and yearly totals counts
    posttotal = 0
    for key, value in adict.iteritems():
        yearsum = 0
        for m, c in value.items():
            yearsum += c
            posttotal += c
            bdict[key] = yearsum

    d = defaultdict(list)
    for k, v in adict.items() + bdict.items():
        d[k].append(v)

    return render_template('archive.html', d=d)

jina2

{% extends "base.html" %}
{% block title %}Archive{% endblock %}
{% block content %}

<dl>
{% for key, value in d.iteritems() %}
    <dt><a href="/{{ key }}">{{ key }}</a> ({{ value[1] }})</dt>
    {% for m, c in value[0].items() %}
       <dd><a href="/{{ key }}/{{ m }}">{{m|month_number}}</a> ({{ c }})</a></dd>
        {{ a }}
    {% endfor %}
{% endfor %}
</dl>


{% endblock %}