Flask SQLalchemy - 多对多 - 显示包含所有标签的照片(或包含所有帖子的博客等)

时间:2015-07-12 07:01:47

标签: python flask flask-sqlalchemy

我是Flask和SQLalchemy的新手。想拥有包含单张照片的网页,该照片会显示分配给该照片的所有标签。

我让SQLalchemy与MYSQL db一起正常工作。很好地检索记录等。

我需要有关flask / SQLalchemy工作流程的帮助:

模型 - > view(从url输入,例如view / photo id) - >模板 - >网页

模型如下:

class Photos(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    filename = db.Column(db.String(100))
    tags = db.relationship(
        'Tags', 
        secondary=photo_tags,
        backref='photos')


class Tags(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    tagname = db.Column(db.String(100))

photo_tags = db.Table('photo_tags',
    db.Column('tag_id', db.Integer, db.ForeignKey('tags.id')),
    db.Column('photo_id', db.Integer, db.ForeignKey('photos.id'))
)

我的观点如下:

@app.route('/phototags/<int:id>')
#@login_required
def phototags(id=None):
    photo_tags =  Tags.query.filter(Tags.photos).filter(id == id).all()
    return render_template(
        'phototags.html', 
        title='PhotoTags',
        message='Your application description page.',
        photo_tags = photo_tags
    )

我的模板如下:

{% extends "layout.html" %}
{% block content %}
<h2>{{ title }}.</h2>
<h3>{{ message }}</h3>
            {% for phototag in photo_tags %}
            <div style="float:left; class=" img-responsive">
                <p><a href="{{ url_for('photo', id=phototag.id)}}">photo</a></p>
                <p><a href="{{ url_for('tag', id=phototag.id)}}"></p>tag</a></p>
                <img src="static/photos/{{ phototag.id }}" width="100" height="100">
            </div>
            {% endfor %}
{% endblock %}

我很确定模型和关联表/模型设置正确。

模板并不完美,因为它目前似乎显示了照片ID的标签ID。我曾尝试做过phototag.photo_id&#39;或者&#39; phototag.filename&#39;但是没有出来。很明显,查看查询并不能解决这个问题。

所以这个观点是我需要帮助的。查询是否正确?是否正确获取了为photo_id传递的url参数?

我的测试数据很简单。我有一张带有photos.id = 1

的照片记录

这有2个相关的Phototags记录:phototags.id = 1(tag.id = 1),phototags.id = 2(tag.id = 2)

当我传递url http://localhost:5555/phototags/1时,我的视图查询会传递标记ID,但更改传递的参数始终会获得相同的标记ID,例如phototags / 2也会获得相同的两个标记。所以查询显然不正确。

我看过几十个例子,它们都与我想要的完全不同。我见过的所有示例/教程/ SO问题/答案都没有显示模型,视图和模板如何协同工作以获得我想要的东西。他们是:

  • 相反,例如相当于照片的标签(希望标签照片)
  • 只是通过照片获取标签的查询(我甚至不认为我会这样做)
  • 有另一个SQLalchemy表示法,包括&#39; sessions&#39;或者&#39; base&#39;而不是&#39; db.model&#39;

我想要的输出是照片ID,因此我可以显示照片及其名称等,还会显示与该照片相关联的标签列表,例如逗号分隔列表。

我很难找到一个演示/示例/教程/ github项目,它指导我完成工作流程所需的工作。

有人可以向我展示一个视图示例,可以从url参数中获取照片ID,然后查询我的模型以获取相关标签吗?

1 个答案:

答案 0 :(得分:2)

从您描述的用例中查询照片而不是photo_tags似乎更合适。 使用视图功能

@app.route('/phototags/<int:id>')
def phototags(id=None):
    photo =  Photo.query.get(id)
    return render_template(
        'phototags.html', 
        title='PhotoTags',
        message='Your application description page.',
        photo = photo
    )

然后,您可以使用html模板中的“标记”关系显示照片并迭代其标记:

{% extends "layout.html" %}
{% block content %}
<h2>{{ title }}.</h2>
<h3>{{ message }}</h3>
            <img src="static/photos/{{ photo.id }}" width="100" height="100">
            {% for phototag in photo.tags %}
            <div style="float:left; class=" img-responsive">
                <p><a href="{{ url_for('photo', id=phototag.id)}}">photo</a></p>
                <p><a href="{{ url_for('tag', id=phototag.id)}}"></p>tag</a></p>
            </div>
            {% endfor %}
{% endblock %}

请注意,我在Photo的查询中使用了get函数。它与

基本相同
Photo.query.filter(id == id).first()

将视图功能和模板从照片标记重命名为照片也是有意义的。

如果要显示标签的所有图像,则必须反转逻辑,查询标签并迭代照片。应该是可能的,因为你定义了一个backref。