使用Flask和JQuery,如何通过" POST"删除记录。方法"性感"方法是什么?

时间:2017-03-16 11:29:30

标签: javascript jquery python twitter-bootstrap flask

我正在使用Flask制作一个小型网络应用。我需要在这个应用程序中实现CRUD操作。我的主要问题是如何实现"删除"适当的操作"性感"办法。我可以实现"删除"操作" GET"最初的方法。但在阅读了大量文件后,我发现这不是一个好办法。

所以我尝试了一些解决方案来实现"删除"操作" POST"方法,最后我使用以下代码:

HTML

{% block mainbody %}
<div class="container">
    <div class="page-header">
        <h3>{{ _('User Setting') }}</h3>
    </div>

    <fieldset>
        <legend><label>{{ _('Article Category') }}</label></legend>
        <table class="col-md-offset-2 col-md-8">
            <tbody>
                {% for article_category in article_categories %}
                <tr>
                    <td>{{ article_category.name }}</td>
                    <td width="30px"><a href="{{ url_for('user.edit_article_category', id=article_category.id) }}"><span class="glyphicon glyphicon-pencil"></span></a></td>
                    <td width="30px"><a href="#" data-record-url="{{ url_for('user.delete_article_category', id=article_category.id) }}" data-record-title="{{ article_category.name }}" data-toggle="modal" data-target="#confirm-delete-modal"><span class="glyphicon glyphicon-trash"></span></a></td>
                </tr>
                {% endfor %}
                <tr>
                    <td><a href="{{ url_for('user.add_article_category') }}" class="btn" style="margin-top:10px"><span class="glyphicon glyphicon-plus"></span> {{ _('Create New Article Category') }}</a></td>
                </tr>
            </tbody>
        </table>
    </fieldset>
</div>

<div class="modal fade" id="confirm-delete-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
                <h4 class="modal-title">{{ _('Confirm Delete') }}</h4>
            </div>
            <div class="modal-body">
                <p>{{ _('You are about to delete this record:') }} <strong><span id="deleted-content"></span></strong>, {{ _('the procedure is irreversible') }}.</p>
                <p>{{ _('Do you want to proceed?') }}</p>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">{{ _('Cancel') }}</button>
                <button type="button" class="btn btn-danger btn-ok">{{ _('Delete') }}</button>
            </div>
        </div>
    </div>
</div>

<script type=text/javascript src="{{ url_for('static', filename='js/jquery-3.1.1.min.js') }}"></script>
<script>
    $(document).ready(function() {
        var csrf_token = "{{ csrf_token() }}";
        $.ajaxSetup({
            beforeSend: function(xhr, settings) {
                if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
                    xhr.setRequestHeader("X-CSRFToken", csrf_token);
                }
            }
        });
        $('#confirm-delete-modal').on('click', '.btn-ok', function(e) {
            var recordUrl = $(this).data('recordUrl');
            $.post(recordUrl, function(data) {
                console.log(data);
            });
            $('#confirm-delete-modal').modal('hide');
        });
        $('#confirm-delete-modal').on('show.bs.modal', function(e) {
            var recordTitle = $(e.relatedTarget).data('recordTitle');
            var recordUrl = $(e.relatedTarget).data('recordUrl');
            $(e.currentTarget).find('#deleted-content').text(recordTitle);
            $(e.currentTarget).find('.btn-ok').data('recordUrl', recordUrl);
        });
        $('#confirm-delete-modal').on('hidden.bs.modal', function() {
            location.reload(false);
        });
    });
</script>
{% endblock %}

烧瓶

@user.route("/setting/article-category/<int:id>/delete", methods=["POST"])
@login_required
def delete_article_category(id):
    deleting_article_category = ArticleCategory.get(ArticleCategory.id == id)
    deleting_article_category.delete_instance()
    return redirect(url_for("user.setting"))

上面的代码确实有效,但至少有两个缺点。

  1. /user/setting (url_for("user.setting"))页面内容会被转移两次。第一次是Flask代码return redirect(url_for("user.setting"))所做的。第二次是JQuery代码location.reload(false)所做的。似乎这两个代码段是重复的。但我不能删除任何一个。如果我删除了JQuery代码,那么在我确认模式并且确实从数据库中删除了记录之后,/user/setting (url_for("user.setting"))页面无法自动刷新,这意味着删除的项目看起来仍然保持在那里直到我手动刷新页面。这肯定是我应该避免的不一致的结果。如果我删除Flask代码return redirect(url_for("user.setting"))或将其更改为return Null,我将从服务器收到500错误。虽然记录仍然可以删除,但我可以从Chrome的Javascript控制台中捕获此错误。我不能忍受这个。
  2. JQuery代码location.reload(false)将下载很多支持的东西,比如bootstrap.css,bootstrap.js,logo.png,而不是纯html文件。即使我使用false参数来要求它尝试从浏览器的缓存中找到这些内容。
  3. 由于上述两个缺点,我认为我的代码效率太低了。谁可以帮我改进我的代码?

    通过使用console.log(data),我注意到Flask代码return redirect(url_for("user.setting"))已经导致JQuery的$.post()操作获取反馈数据中的新页面内容。新页面内容非常正确,这意味着已删除的记录不再列在那里。但是没有可以使用这种正确数据的页面刷新机制。我认为这是导致效率低下的关键。

    我在想Flask应该提供一些安全删除DB记录的简单方法。只是一个删除操作,比编辑或添加要复杂得多。是因为我不知道如何使用Form来实现它,还是有其他理由让删除操作太难?我是初学者,所以也许我的想法是错误的。

    对我有什么建议吗?谢谢!

    数据包捕获工具更新 - Charles屏幕截图: enter image description here

1 个答案:

答案 0 :(得分:2)

实际上,您无需发送完整页面以回复DELETE请求。空HTTP 204响应是此类请求的标准返回值:

pip install C:\Users\Administrator\Downloads\pysqlite-2.8.3-cp27-cp27m-win_amd64.whl
pysqlite-2.8.3-cp27-cp27m-win_amd64.whl is not a supported wheel on this platform.
You are using pip version 7.1.2, however version 9.0.1 is available.

您无需担心刷新页面,因为浏览器从其缓存中获取所有静态文件。当然,除非您使用def delete_article_category(id): deleting_article_category = ArticleCategory.get(ArticleCategory.id == id) deleting_article_category.delete_instance() return Response(status=204) 。检查应用程序的日志:很可能它提供HTTP 304代码(未修改)的静态文件,如下所示:

location.reload(true)