Solved - Flask Tutorial 01 : Bổ sung button Delete nhưng không delete đc dữ liệu trong SQLite DB



  • Mình mới học Flask đang làm theo hướng dẫn từ trang chủ của Flask, viết 01 simple blog. Mình đã copy về và chạy OK, sau đó có modify bổ sung thêm nút Delete cạnh nút Share. Sau khi chạy python flaskr.py thì OK nhưng click button delete thì ko Delete đc.
    Đoạn code mình copy từ class add_entry, chỉ sửa lại câu SELECT thành câu DELETE.

    @app.route('/delete', methods=['POST'])
    def delete_entry():
        if not session.get('logged_in'):
            abort(401)
        db = get_db()
        db.execute('DELETE FROM entries')
        db.commit()
        flash('Now all entry was successfully deleted.')
        return redirect(url_for('show_entries'))
    

    Mình tạo class delete_entry như bên dưới nhưng vẫn không delete đc dữ liệu trong DB.
    Nhờ các bạn chỉ giúp mình còn thiếu chỗ nào ?

    Phân bổ thư mục trong app firstapp như sau :

    1.File flaskr.py

    # -*- coding: utf-8 -*-
    """
        Flaskr
        ~~~~~~
        A microblog example application written as Flask tutorial with
        Flask and sqlite3.
        :copyright: (c) 2015 by Armin Ronacher.
        :license: BSD, see LICENSE for more details.
    """
    
    import os
    from sqlite3 import dbapi2 as sqlite3
    from flask import Flask, request, session, g, redirect, url_for, abort, \
         render_template, flash
    
    
    # create our little application :)
    app = Flask(__name__)
    
    # Load default config and override config from an environment variable
    app.config.update(dict(
        DATABASE=os.path.join(app.root_path, 'flaskr.db'),
        DEBUG=True,
        SECRET_KEY='development key',
        USERNAME='admin',
        PASSWORD='default'
    ))
    app.config.from_envvar('FLASKR_SETTINGS', silent=True)
    
    
    def connect_db():
        """Connects to the specific database."""
        rv = sqlite3.connect(app.config['DATABASE'])
        rv.row_factory = sqlite3.Row
        return rv
    
    
    def init_db():
        """Initializes the database."""
        db = get_db()
        with app.open_resource('schema.sql', mode='r') as f:
            db.cursor().executescript(f.read())
        db.commit()
    
    
    @app.cli.command('initdb')
    def initdb_command():
        """Creates the database tables."""
        init_db()
        print('Initialized the database.')
    
    
    def get_db():
        """Opens a new database connection if there is none yet for the
        current application context.
        """
        if not hasattr(g, 'sqlite_db'):
            g.sqlite_db = connect_db()
        return g.sqlite_db
    
    
    # close connection to db
    @app.teardown_appcontext
    def close_db(error):
        """Closes the database again at the end of the request."""
        if hasattr(g, 'sqlite_db'):
            g.sqlite_db.close()
    
    
    @app.route('/')
    def show_entries():
        db = get_db()
        cur = db.execute('select id, title, text from entries')
        entries = cur.fetchall()
        return render_template('show_entries.html', entries=entries)
    
    
    @app.route('/add', methods=['POST'])
    def add_entry():
        if not session.get('logged_in'):
            abort(401)
        db = get_db()
        db.execute('insert into entries (title, text) values (?, ?)',
                   [request.form['title'], request.form['text']])
        db.commit()
        flash('New entry was successfully posted')
        return redirect(url_for('show_entries'))
    
    
    @app.route('/delete', methods=['POST'])
    def delete_entry():
        if not session.get('logged_in'):
            abort(401)
        db = get_db()
        db.execute('DELETE FROM entries')
        db.commit()
        flash('Now all entry was successfully deleted.')
        return redirect(url_for('show_entries'))
    
    
    @app.route('/login', methods=['GET', 'POST'])
    def login():
        error = None
        if request.method == 'POST':
            if request.form['username'] != app.config['USERNAME']:
                error = 'Invalid username'
            elif request.form['password'] != app.config['PASSWORD']:
                error = 'Invalid password'
            else:
                session['logged_in'] = True
                flash('You were logged in')
                return redirect(url_for('show_entries'))
        return render_template('login.html', error=error)
    
    
    @app.route('/logout')
    def logout():
        session.pop('logged_in', None)
        flash('You were logged out')
        return redirect(url_for('show_entries'))
    
    if __name__ == '__main__':
        app.run(port=5000, debug=True)
    

    2.File show_entries.html :

    {% extends "layout.html" %}
    {% block body %}
      {% if session.logged_in %}
        <form action="{{ url_for('add_entry') }}" method="post" class="add-entry">
          <dl>
              <dt>Title:
              <dd><input type="text" size="30" name="title">
              <dt>Text:
              <dd><textarea name="text" rows="5" cols="40"></textarea>
              <dd><input type="submit" value="Share"><input type="submit" value="Clear DB">
    
          </dl>
        </form>
      {% endif %}
      <ul class="entries">
      {% for entry in entries %}
        <li><h1>{{ entry.id }}</h1><h2>{{ entry.title }}</h2>{{ entry.text|safe }}</li>
      {% else %}
        <li><em>Unbelievable.  No entries here so far</em></li>
      {% endfor %}
      </ul>
    {% endblock %}
    

    3.File login.html :

    {% extends "layout.html" %}
    {% block body %}
      <h2>Login</h2>
      {% if error %}<p class="error"><strong>Error:</strong> {{ error }}{% endif %}
      <form action="{{ url_for('login') }}" method="post">
        <dl>
          <dt>Username:
          <dd><input type="text" name="username">
          <dt>Password:
          <dd><input type="password" name="password">
          <dd><input type="submit" value="Login">
        </dl>
      </form>
    {% endblock %}
    

    4.File style.css

    body            { font-family: sans-serif; background: #eee; }
    a, h1, h2       { color: #377BA8; }
    h1, h2          { font-family: 'Georgia', serif; margin: 0; }
    h1              { border-bottom: 2px solid #eee; }
    h2              { font-size: 1.2em; }
    
    .page           { margin: 2em auto; width: 35em; border: 5px solid #ccc;
                      padding: 0.8em; background: white; }
    .entries        { list-style: none; margin: 0; padding: 0; }
    .entries li     { margin: 0.8em 1.2em; }
    .entries li h2  { margin-left: -1em; }
    .add-entry      { font-size: 0.9em; border-bottom: 1px solid #ccc; }
    .add-entry dl   { font-weight: bold; }
    .metanav        { text-align: right; font-size: 0.8em; padding: 0.3em;
                      margin-bottom: 1em; background: #fafafa; }
    .flash          { background: #CEE5F5; padding: 0.5em;
                      border: 1px solid #AACBE2; }
    .error { background: #F0D6D6; padding: 0.5em; }
    

    5.File schema.sql

    drop table if exists entries;
    create table entries (
      id integer primary key autoincrement,
      title text not null,
      'text' text not null
    );
    

    Edited : Bổ sung thêm {% endblock %} vào cuối dòng của file show_entries.html

    {% extends "layout.html" %}
    {% block body %}
      {% if session.logged_in %}
        <form action="{{ url_for('add_entry') }}" method="post" class="add-entry">
          <dl>
              <dt>Title:
              <dd><input type="text" size="30" name="title">
              <dt>Text:
              <dd><textarea name="text" rows="5" cols="40"></textarea>
              <dd><input type="submit" value="Share">
          </dl>
        </form>
        <form action="{{ url_for('delete_entry') }}" method="post" class="delete-entry">
          <dl>
              <dd><input type="submit" value="Delete">
          </dl>
        </form>
      {% endif %}
      <ul class="entries">
      {% for entry in entries %}
        <li><h1>{{ entry.id }}</h1><h2>{{ entry.title }}</h2>{{ entry.text|safe }}</li>
      {% else %}
        <li><em>Unbelievable.  No entries here so far</em></li>
      {% endfor %}
      </ul>
    {% endblock %}
    


  • Mình check thì do mình chèn sai button Delete vào form action="{{ url_for('add_entry') }}. Mình đã tạo mới 01 form action="{{ url_for('delete_entry') }} và chèn mỗi button Delete vào rồi chạy thì bị lỗi như bên dưới.
    Lúc này nội dung của file show_entries.html là :

    {% extends "layout.html" %}
    {% block body %}
      {% if session.logged_in %}
        <form action="{{ url_for('add_entry') }}" method="post" class="add-entry">
          <dl>
              <dt>Title:
              <dd><input type="text" size="30" name="title">
              <dt>Text:
              <dd><textarea name="text" rows="5" cols="40"></textarea>
              <dd><input type="submit" value="Share">
          </dl>
        </form>
        <form action="{{ url_for('delete_entry') }}" method="post" class="delete-entry">
          <dl>
              <dd><input type="submit" value="Delete">
          </dl>
        </form>
      {% endif %}
      <ul class="entries">
      {% for entry in entries %}
        <li><h1>{{ entry.id }}</h1><h2>{{ entry.title }}</h2>{{ entry.text|safe }}</li>
      {% else %}
        <li><em>Unbelievable.  No entries here so far</em></li>
      {% endfor %}
      </ul>
    

    Log lỗi như bên dưới.

    python flaskr.py
     * Restarting with stat
     * Debugger is active!
     * Debugger pin code: 155-557-976
     * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
    127.0.0.1 - - [25/Aug/2016 15:29:56] "GET / HTTP/1.1" 500 -
    Traceback (most recent call last):
      File "C:\Python27\lib\site-packages\flask\app.py", line 2000, in __call__
        return self.wsgi_app(environ, start_response)
      File "C:\Python27\lib\site-packages\flask\app.py", line 1991, in wsgi_app
        response = self.make_response(self.handle_exception(e))
      File "C:\Python27\lib\site-packages\flask\app.py", line 1567, in handle_exception
        reraise(exc_type, exc_value, tb)
      File "C:\Python27\lib\site-packages\flask\app.py", line 1988, in wsgi_app
        response = self.full_dispatch_request()
      File "C:\Python27\lib\site-packages\flask\app.py", line 1641, in full_dispatch_request
        rv = self.handle_user_exception(e)
      File "C:\Python27\lib\site-packages\flask\app.py", line 1544, in handle_user_exception
        reraise(exc_type, exc_value, tb)
      File "C:\Python27\lib\site-packages\flask\app.py", line 1639, in full_dispatch_request
        rv = self.dispatch_request()
      File "C:\Python27\lib\site-packages\flask\app.py", line 1625, in dispatch_request
        return self.view_functions[rule.endpoint](**req.view_args)
      File "C:\Users\xxx\PycharmProjects\firstapp\flaskr.py", line 75, in show_entries
        return render_template('show_entries.html', entries=entries)
      File "C:\Python27\lib\site-packages\flask\templating.py", line 133, in render_template
        return _render(ctx.app.jinja_env.get_or_select_template(template_name_or_list),
      File "C:\Python27\lib\site-packages\jinja2\environment.py", line 851, in get_or_select_template
        return self.get_template(template_name_or_list, parent, globals)
      File "C:\Python27\lib\site-packages\jinja2\environment.py", line 812, in get_template
        return self._load_template(name, self.make_globals(globals))
      File "C:\Python27\lib\site-packages\jinja2\environment.py", line 786, in _load_template
        template = self.loader.load(self, name, globals)
      File "C:\Python27\lib\site-packages\jinja2\loaders.py", line 125, in load
        code = environment.compile(source, name, filename)
      File "C:\Python27\lib\site-packages\jinja2\environment.py", line 565, in compile
        self.handle_exception(exc_info, source_hint=source_hint)
      File "C:\Python27\lib\site-packages\jinja2\environment.py", line 754, in handle_exception
        reraise(exc_type, exc_value, tb)
      File "C:\Users\xxx\PycharmProjects\firstapp\templates\show_entries.html", line 24, in template
        {% endfor %}
    TemplateSyntaxError: Unexpected end of template. Jinja was looking for the following tags: 'endblock'. The innermost block that needs to be closed is 'block'.
    127.0.0.1 - - [25/Aug/2016 15:30:00] "GET /?__debugger__=yes&cmd=resource&f=style.css HTTP/1.1" 200 -
    127.0.0.1 - - [25/Aug/2016 15:30:00] "GET /?__debugger__=yes&cmd=resource&f=jquery.js HTTP/1.1" 200 -
    127.0.0.1 - - [25/Aug/2016 15:30:00] "GET /?__debugger__=yes&cmd=resource&f=debugger.js HTTP/1.1" 200 -
    127.0.0.1 - - [25/Aug/2016 15:30:00] "GET /?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 200 -
    127.0.0.1 - - [25/Aug/2016 15:30:00] "GET /?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 200 -
    127.0.0.1 - - [25/Aug/2016 15:30:01] "GET /?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 200 -
    127.0.0.1 - - [25/Aug/2016 15:30:31] "GET / HTTP/1.1" 500 -
    Traceback (most recent call last):
      File "C:\Python27\lib\site-packages\flask\app.py", line 2000, in __call__
        return self.wsgi_app(environ, start_response)
      File "C:\Python27\lib\site-packages\flask\app.py", line 1991, in wsgi_app
        response = self.make_response(self.handle_exception(e))
      File "C:\Python27\lib\site-packages\flask\app.py", line 1567, in handle_exception
        reraise(exc_type, exc_value, tb)
      File "C:\Python27\lib\site-packages\flask\app.py", line 1988, in wsgi_app
        response = self.full_dispatch_request()
      File "C:\Python27\lib\site-packages\flask\app.py", line 1641, in full_dispatch_request
        rv = self.handle_user_exception(e)
      File "C:\Python27\lib\site-packages\flask\app.py", line 1544, in handle_user_exception
        reraise(exc_type, exc_value, tb)
      File "C:\Python27\lib\site-packages\flask\app.py", line 1639, in full_dispatch_request
        rv = self.dispatch_request()
      File "C:\Python27\lib\site-packages\flask\app.py", line 1625, in dispatch_request
        return self.view_functions[rule.endpoint](**req.view_args)
      File "C:\Users\xxx\PycharmProjects\firstapp\flaskr.py", line 75, in show_entries
        return render_template('show_entries.html', entries=entries)
      File "C:\Python27\lib\site-packages\flask\templating.py", line 133, in render_template
        return _render(ctx.app.jinja_env.get_or_select_template(template_name_or_list),
      File "C:\Python27\lib\site-packages\jinja2\environment.py", line 851, in get_or_select_template
        return self.get_template(template_name_or_list, parent, globals)
      File "C:\Python27\lib\site-packages\jinja2\environment.py", line 812, in get_template
        return self._load_template(name, self.make_globals(globals))
      File "C:\Python27\lib\site-packages\jinja2\environment.py", line 786, in _load_template
        template = self.loader.load(self, name, globals)
      File "C:\Python27\lib\site-packages\jinja2\loaders.py", line 125, in load
        code = environment.compile(source, name, filename)
      File "C:\Python27\lib\site-packages\jinja2\environment.py", line 565, in compile
        self.handle_exception(exc_info, source_hint=source_hint)
      File "C:\Python27\lib\site-packages\jinja2\environment.py", line 754, in handle_exception
        reraise(exc_type, exc_value, tb)
      File "C:\Users\xxx\PycharmProjects\firstapp\templates\show_entries.html", line 24, in template
        {% endfor %}
    TemplateSyntaxError: Unexpected end of template. Jinja was looking for the following tags: 'endblock'. The innermost block that needs to be closed is 'block'.
    127.0.0.1 - - [25/Aug/2016 15:30:31] "GET /?__debugger__=yes&cmd=resource&f=style.css HTTP/1.1" 200 -
    127.0.0.1 - - [25/Aug/2016 15:30:31] "GET /?__debugger__=yes&cmd=resource&f=jquery.js HTTP/1.1" 200 -
    127.0.0.1 - - [25/Aug/2016 15:30:31] "GET /?__debugger__=yes&cmd=resource&f=debugger.js HTTP/1.1" 200 -
    127.0.0.1 - - [25/Aug/2016 15:30:31] "GET /?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 200 -
    127.0.0.1 - - [25/Aug/2016 15:30:31] "GET /?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 200 -
    127.0.0.1 - - [25/Aug/2016 15:30:31] "GET /?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 200 -
    


  • Theo log thì template của bạn thiếu endblock ở dòng cuối.

    Bạn muốn xóa từng entry riêng lẻ hay muốn empty cả table entries luôn ?



  • @nguyenkims Thank bạn đã xem code này. :D
    Mình muôn delete toàn bộ trong table entries.



  • @jackvo đã nói trong Flask Tutorial : Bổ sung button Delete nhưng không delete đc dữ liệu trong SQLite DB:

    @nguyenkims Thank bạn đã xem code này. :D
    Mình muôn delete toàn bộ trong table entries.

    Thank bạn đã chỉ giúp mình, lỗi đã fixed.


Hãy đăng nhập để trả lời
 

Có vẻ như bạn đã mất kết nối tới Cộng đồng Python Việt Nam, vui lòng đợi một lúc để chúng tôi thử kết nối lại.