首页 > 解决方案 > 如何在 Flask 中增加我的查看计数器?

问题描述

我在做什么的总结和背景:

我正在创建一个允许您添加和存储食谱的应用程序,并且我希望能够使用每个食谱收到的查看次数来组织我的食谱列表。我应该解释一下,我有一个食谱列表,如果您单击该列表中一个食谱的标题,它将带您进入一个新页面并显示该食谱。这样我可以将我的应用程序组织成三类列表(早餐、午餐和晚餐)。

我正在使用MongoDB来托管我的键/值对(“views”:0),并且我希望能够在每次有人刷新页面时将“views”的值增加 +1。我将在下面提供我的代码,但我认为我的问题是我似乎无法在我的 HTML 或 MongoDB 中增加值。让我解释一下:我几乎可以肯定我的路由代码是正确的。我已经看过很多关于在 MongoDB 中使用 $inc 值的适当方法的教程,但我相信我的 HTML 中遗漏了一些东西来正确对应该代码,我不确定它是什么。

当我运行此代码时,它仍然可以工作并且没有错误警告,但是当我进入任何食谱页面时,当我刷新该页面时,视图计数器不会改变。它只是保持在0。

我还应该说我有两条独立的路线,我认为在这种情况下它们彼此相关:我有一个显示食谱页面的“view_recipe”路线,还有一个用于计算视图的“view_count”路线。我将在下面提供这两个以及我的 HTML 供大家检查。

到目前为止我尝试过的:

对于我的食谱应用程序,我遵循了有关如何 $inc 我的键/值的 Youtube 教程,但是我不确定这是我需要提供给我的 HTML 的信息。基于其他示例,我在 HTML 中对应的视图信息是这样的:

<a href="{{url_for('view_recipe', recipe_id=recipe._id)}}" class="waves-effect waves-light btn btn_small blue">{{recipe.views})</a>

我已经为路线提供了一个 url_,并制作了我认为相关的 recipe_id=recipe._id,就像我在其他用于定位该 id 的示例中看到的那样。

我的代码:

这是我的"view_recipe""view_count"路线:

@app.route('/view_recipe/<recipe_id>')
def view_recipe(recipe_id):
    the_recipe =  mongo.db.recipes.find_one({"_id": ObjectId(recipe_id)})
    return render_template('view_recipe.html', recipe=the_recipe)

@app.route('/view_count/<recipe_id>')
def view_count(recipe_id):
    mongo.db.recipes
    recipes.update({'_id': str(recipe_id)}, {'$inc': {'views': int(1)}})
    return url_for('view_recipe.html')

这是我在放置{{recipe.view}}的“view_recipe.html”中提供的查看次数部分

<a href="{{url_for('view_recipe', recipe_id=recipe._id)}}" class="waves-effect waves-light btn btn_small blue">{{recipe.views})</a>

当我运行此代码时会发生什么与我期望会发生什么:

代码运行,但是它并没有像我期望的那样增加。当我刷新页面时,计数器只是保持在 0 并且不会上升。我希望一旦页面被刷新,计数器的值将会增加并显示在浏览器中并在我的 MongoDb 集合中更新。

以防万一...

如果您需要更多信息,或者我不够清楚或解释得不够清楚,请告诉我,我会修复它。

谢谢你。

标签: pythonmongodbflask

解决方案


可能需要对 Mongo DB 的东西进行一些调整,但为什么不只使用view_count没有路由的函数,因为它不需要通过 URL 调用。而是直接在view_recipe函数中调用它。

@app.route('/view_recipe/<int:recipe_id>')
def view_recipe(recipe_id):
    the_recipe =  mongo.db.recipes.find_one({"_id": recipe_id})
    view_count(recipe_id) # call the other function here.
    return render_template('view_recipe.html', recipe=the_recipe)

def view_count(recipe_id):
    recipes = mongo.db.recipes
    recipes.update({'_id': recipe_id}, {'$inc': {'views': 1}})
    return True
  • 在路由中,参数应该是<int:recipe_id>确保用户输入是整数。
  • 第二个函数不再需要返回render_template,而是返回 True。
  • 您不能只调用mongo.db.recipes视图函数。我已经改变了这个,所以你设置receipes为这个,然后访问receipes.update. 这与调用相同mongo.db.recipes.update()

编辑

我假设你正在使用pymongo. 注意上面的变化。

我很好奇,我启动了一个 mongo DB 测试盒并尝试了这个。我已经测试并上传了这个要点,其中包含一个显示我的初始配置的文件,以及一个导入来演示这一点shell.py的准系统烧瓶应用程序。db.py

我认为你的问题是ObjectID()实际上做了一些不相关的事情。你应该只需要传递recipe_id我的代码演示的。然后我可以通过几次执行来测试curl http://localhost:5000/1并观察每次增加计数的开发服务器输出:

Db script:  {'_id': 1, 'text': 'TEST', 'counter': 5}
Flask says:  {'_id': 1, 'text': 'TEST', 'counter': 6}
127.0.0.1 - - [30/Dec/2018 01:22:21] "GET /1 HTTP/1.1" 200 -
Flask says:  {'_id': 1, 'text': 'TEST', 'counter': 7}
127.0.0.1 - - [30/Dec/2018 01:22:22] "GET /1 HTTP/1.1" 200 -
Flask says:  {'_id': 1, 'text': 'TEST', 'counter': 8}
127.0.0.1 - - [30/Dec/2018 01:22:22] "GET /1 HTTP/1.1" 200 -

推荐阅读