【问题标题】:Manage Multiple Params with GET Flask restful MongoEngine Clean Code使用 GET Flask restful MongoEngine Clean Code 管理多个参数
【发布时间】:2020-03-06 15:12:52
【问题描述】:

我正在使用flask_restful 创建一个API,并且我想使用将由GET、tag 和author 传递的两个参数进行搜索。

使用下面的代码我可以做到这一点。但是,我必须传递这两个参数。我希望用户传递的任何参数仍然搜索它,

示例: 如果我通过了 tag=tech,则响应应该包含所有带有标签技术和所有作者的新闻,如果我也通过了作者,它应该将标签视为全部 - 我想你明白了 -

class ArticleAPI(Resource):
    def get(self):
        tag=request.args.get('tag','')
        auth=request.args.get('author','')

        news = News.objects.filter(topic=tag,author=auth).to_json()
        return Response(news, mimetype="application/json", status=200)

我知道我可以像这样做很长时间,但它看起来很丑:`(

    if tag is not None and auth is not None :
            news = News.objects.filter(topic=tag,author=auth).to_json()
        elif tag is not None :
            news = News.objects.filter(topic=tag).to_json()
        elif auth is not  None:
            news = News.objects.filter(author=auth).to_json()

我正在使用 Flask_mongoengine

from flask_mongoengine import MongoEngine

db = MongoEngine()

def initialize_db(app):
    db.init_app(app)

【问题讨论】:

    标签: python mongodb flask mongoengine flask-mongoengine


    【解决方案1】:

    我认为您是在问如何以更简洁的方式将关键字参数传递给 .filter() 方法。

    According to the mongoengine docs, .filter() is an alias for __call__()。它采用Query 对象或**query 参数的关键字参数。您的代码使用关键字样式。

    您可以将tagauth 变量放入dictthen unpack them using a double splat as keyword arguments.

    类似这样的:

    fdict = dict()
    if tag : fdict['tag'] = tag
    if auth: fdict['auth'] = auth
    
    news = News.objects.filter(**fdict).to_json()
    

    现在您可以根据需要添加任意数量的这些参数,并且应该使用相同的语法。

    You could just pass in all query params at once.这是我能想到的最干净的方式:

    news = News.objects.filter(**request.args).to_json()
    

    也就是说,盲目地获取用户提供的数据并将其传递到数据库中通常需要进行安全权衡。我对 Mongo 如何处理这个问题知之甚少,无法明智地谈论这里的最佳实践。另外,您在 UI 端命名的名称在 DB 端可能不同。

    This is also possible using a Query object, 不过好久没做MongoDB的东西了,语法好像很具体,这里就不尝试了。 :)

    【讨论】:

    • filter 有一个很好的功能来选择带有 __icontains 的行,像这样 news = News.objects.filter(headline__icontains = headline).to_json() 有没有办法将它添加到 dict 或做 clean
    • 是的,只需 fdict['tag_icontains'] = tag 或任何字段名称即可
    • 这个想法是我想给用户 3 个字段来搜索文章输入文本,他可以输入任何关键词,选择标签选项,并选择作者选项。所以用户输入的任何东西都应该给他他想要的东西
    • 如果您提供多个可能的关键字,您可能需要查看Query 对象语法。您可以执行Q(keyword='keyword1') | Q(keyword='keyword2') 之类的操作来搜索所有可能的变体。您也可以动态构建它,但会更复杂。
    猜你喜欢
    • 1970-01-01
    • 2018-01-07
    • 2015-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多