如何使用Flask提供HTML和JSON内容?

时间:2022-04-27 16:54:37

I'd like to setup a Flask app that has both a GUI and API component. So here's a simple example that retrieves a list of groups:

我想设置一个同时具有GUI和API组件的Flask应用程序。所以这是一个检索组列表的简单示例:

def get_groups():
    groups = db.session.query(SgmGroup.group_name).order_by(SgmGroup.group_name).all()
    return [group.group_name for group in groups]

@app.route('/list')
def group_list():
    groups_list = get_groups()
    return render_template('groups.html', groups=groups_list)

So far so good - this will give the user an HTML list of users, maybe in a table or some other nice GUI format.

到目前为止一切都很好 - 这将为用户提供HTML用户列表,可能是表格或其他一些不错的GUI格式。

But I'd also like to serve JSON content for API requests:

但我也想为API请求提供JSON内容:

@app.route('/api/list')
def api_group_list():
    groups_list = get_groups()
    return jsonify({'groups': group_list})

This works - but is this a good idea? I have two questions:

这有效 - 但这是一个好主意吗?我有两个问题:

1) Is this the appropriate way to use Flask when I have two different types of content? Make an /endpoint URL for web browsers (HTML), and an identical /api/endpoint URL to handle API requests (JSON)?

1)当我有两种不同类型的内容时,这是使用Flask的合适方式吗?为Web浏览器(HTML)创建/端点URL,以及处理API请求(JSON)的相同/ api /端点URL?

2) Or should I combine these two endpoints into a single function? That would seem to be neater, but how can you determine which endpoint the user accessed? That is, can the pseudocode below be done?

2)或者我应该将这两个端点合并为一个函数?这看起来更整洁,但是如何确定用户访问的端点?也就是说,下面的伪代码可以完成吗?

@app.route('/list')
@app.route('/api/list')
def group_list():
    groups_list = get_groups()

    if <user arrived here via the /list endpoint>:
        return render_template('groups.html', groups=groups_list)

    elif <user arrived here via the /api/list endpoint>:
        return jsonify({'groups': group_list})

2 个解决方案

#1


1  

To answer your second question:

回答你的第二个问题:

from flask import request

@app.route('/')
@app.route('/json')
def index():
    if request.path == '/json':
        return {}
    return render_template('index.html')

The doc reference is here.

文档参考在这里。

#2


0  

You could also split the requests by method to different functions, like so:

您还可以通过方法将请求拆分为不同的函数,如下所示:

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        return {}
    else:
        return render_template('index.html')

For project structuring reasons though I would suggest to split up routes to api's and templates in different files.

出于项目结构的原因,我建议将路由拆分为api和不同文件中的模板。

project
├── app
|    ├── views.py
|    └── api.py
└──.....

#1


1  

To answer your second question:

回答你的第二个问题:

from flask import request

@app.route('/')
@app.route('/json')
def index():
    if request.path == '/json':
        return {}
    return render_template('index.html')

The doc reference is here.

文档参考在这里。

#2


0  

You could also split the requests by method to different functions, like so:

您还可以通过方法将请求拆分为不同的函数,如下所示:

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        return {}
    else:
        return render_template('index.html')

For project structuring reasons though I would suggest to split up routes to api's and templates in different files.

出于项目结构的原因,我建议将路由拆分为api和不同文件中的模板。

project
├── app
|    ├── views.py
|    └── api.py
└──.....