Build a CRUD App with SQLAlchemy - Delete

Deletes deal with removing existing objects in our database.

SQL 语句

DELETE FROM table_name
WHERE condition;

SQLAlchemy 语句

todo = Todo.query.get(todo_id)
db.session.delete(todo)
# or
Todo.query.filter_by(id=todo_id).delete()

db.session.commit()

实现Delete步骤:

  1. Loop through every items and show a delete button
  2. Pressing the delete button sends a request that includes which item to delete
  3. The controller takes the user input, and notifies the models to delete the item object ID
  4. On successful deletion by the models, the controller should notify the view to refresh the page and redirect to our homepage, showing a fresh of all items to now exclude the removed item.

Using the DELETE method
Requests that delete objects should use the method DELETE, as opposed to POST, GET, etc. when sending requests to the server.


<!DOCTYPE html>
<html>
    <head>
        <title>Todo app</title>
        <style>
            .hidden {
      
      
                display:none;
            }

            ul {
      
      
                list-style: none;
                padding: 0;
                margin: 0;
                width: 200px;
            }

            li {
      
      
                /* clear: both; */
                padding-top: 10px;
            }

            li button {
      
      
                -webkit-appearance: none;
                border: none;
                outline: none;
                color: red;
                float: right;
                cursor: pointer;
                font-size: 20px;
            }
        </style>
    </head>
    <body>
        <form id="form">
            <input type="text" id="description" name="description" />
            <input type="submit" value="Create" />
        </form>
        <div id="error" class="hidden">Something went wrong!</div>
        <ul id="todos">
            {% for d in data %}
                <li>
                    <input class="check-completed" data-id="{
     
     { d.id }}" type="checkbox" {% if d.completed %} checked {% endif %} />
                        {
   
   { d.description }}
                    <button class="delete-button" data-id="{
     
     { d.id }}"> X </button>
                </li>
            {% endfor %}
        </ul>
        <script>
            // Loop over all of the button 
            const deleteBtns = document.querySelectorAll('.delete-button');
            for (let i = 0; i < deleteBtns.length; i++) {
      
      
                const btn = deleteBtns[i];
                btn.onclick = function(e) {
      
      
                    console.log(e);
                    const todoId = e.target.dataset['id'];
                    fetch('/todos/' + todoId, {
      
      
                        method: 'DELETE'
                    });
                }
            }


            // Loop over all of these checkbox elements and listen to the change event with a on change function.
            const checkboxes = document.querySelectorAll('.check-completed');
            for (let i = 0; i < checkboxes.length; i++) {
      
      
                const checkbox = checkboxes[i];
                checkbox.onchange = function(e) {
      
      
                    console.log('event', e);
                    const newCompleted = e.target.checked;
                    const todoId = e.target.dataset['id'];
                    fetch('/todos/' + todoId + '/set-completed', {
      
      
                        method: 'POST',
                        body: JSON.stringify({
      
      
                            'completed': newCompleted
                        }),
                        headers: {
      
      
                            'Content-Type': 'application/json'
                        }
                    })
                    .then(function() {
      
      
                        document.getElementById('error').className = 'hidden';
                    })
                    .catch(function() {
      
      
                        document.getElementById('error').className = '';
                    })
                }
            }


            // Select on the form
            // onsubmit handler to default wound up sending information to the server
            // Using the event object, e
            document.getElementById('form').onsubmit = function(e) {
      
      
                // The default behaviro would have done that full page refresh and 
                // submitted it using the method and action attributes up
                e.preventDefault();

                // Send the post requests asynchronously using fetch
                fetch('/todos/create', {
      
      
                    method: 'POST',
                    body: JSON.stringify({
      
      
                        // The value of whatever the user has typed into the description field.
                        'description': document.getElementById('description').value
                    }),
                    headers: {
      
      
                        'Content-Type': 'application/json'
                    }
                })
                // give back a promise by which we can then use the 
                // then method
                // callback should give us back a response
                .then(function(response) {
      
      
                    // parse out the response which will initially be a string as a JSON response
                    return response.json();
                })
                // manipulate the JSON response 
                .then(function(jsonResponse) {
      
      
                    console.log(jsonResponse);
                    // Append a child Li element here
                    const liItem = document.createElement('LI');
                    liItem.innerHTML = jsonResponse['description'];
                    document.getElementById('todos').appendChild(liItem);
                    // it did succeed
                    document.getElementById("error").className = 'hidden';
                })
                // catch handler
                .catch(function() {
      
      
                    // Remove the class name
                    document.getElementById("error").className = '';
                })
            }
        </script>
    </body>
</html>
from flask import Flask, render_template, request, redirect, url_for, jsonify
from flask_sqlalchemy import SQLAlchemy
import sys
from flask_migrate import Migrate

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgres://username@localhost:5432/todoapp'
db = SQLAlchemy(app)

# Link to Flask app as well as the SQLAlchemy database
# migrate will do is start it up so that we can start using the Flask databae migrate commands to began initializing migrations
# and upgrading and downgrading and generating migrations as well.
migrate = Migrate(app, db)

class Todo(db.Model):
    __tablename__ = 'todos'
    id = db.Column(db.Integer, primary_key=True)
    description = db.Column(db.String(), nullable=False)
    completed = db.Column(db.Boolean, nullable=False, default=False)

    def __repr__(self):
        return f'<Todo {
      
      self.id} {
      
      self.description}>'

# Ensure the tables are created for all the models that we've created and they haven't been created.
# db.create_all()

@app.route('/todos/create', methods=['POST'])
def create_todo():
    error = False
    body = {
    
    }
    try:
        # get_json is that it fetches the JSON body that was sent to an object key description.
        description = request.get_json()['description']
        todo = Todo(description=description)
        db.session.add(todo)
        db.session.commit()
        body['description'] = todo.description
    except:
        error = True
        db.session.rollback()
        # debugging sentence
        print(sys.exc_info())
    finally:
        db.session.close()
    if not error:
        # return a useful JSON object that includes that description.
        # jsonify will return JSON data to the client for us.
        # whatever we pass in as our JSON object.
        return jsonify(body)

@app.route('/todos/<todo_id>/set-completed', methods=['POST'])
def set_completed_todo(todo_id):
    try:
        completed = request.get_json()['completed']
        print('completed', completed)
        todo = Todo.query.get(todo_id)
        todo.completed = completed
        db.session.commit()
    except:
        db.session.rollback()
    finally:
        db.session.close()
    return redirect(url_for('index'))

@app.route('/todos/<todo_id>', methods=['DELETE'])
def delete_todo(todo_id):
    try:
        Todo.query.filter_by(id=todo_id).delete()
        db.session.commit()
    except:
        db.session.rollback()
    finally:
        db.session.close()
    return jsonify({
    
     'success': True })



@app.route('/')
def index():
    return render_template('index.html', data=Todo.query.order_by('id').all())


猜你喜欢

转载自blog.csdn.net/BSCHN123/article/details/121496182