如何在Flask中增加View计数器?

时间:2018-12-28 14:43:41

标签: python mongodb flask

我正在做的事情的摘要和背景:

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

我正在使用 MongoDB 托管我的键/值对(“ views”:0)我希望能够增加每当有人刷新页面时,“观看次数”就会+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')

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

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

运行此代码时发生的情况与我希望发生的情况:

代码可以运行,但是不会像我期望的那样增加。刷新页面时,计数器仅停留在0且不会增加。我希望页面刷新后,计数器的值将递增并显示在浏览器中,并在我的MongoDb集合中更新。

以防万一...

如果您需要更多信息,或者如果我不够清楚或不能很好地解释这一点,请告诉我,我会解决。

谢谢。

1 个答案:

答案 0 :(得分:0)

可能需要对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测试盒并尝试了这个。我已经测试并上传了this gist,其中包含显示我的初始配置的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 -