es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo actualizar MongoDB usando un botón en HTML, pymongo

Tengo un archivo base.html que tiene elementos y un botón para que el usuario haga clic.


<p class="card-text">{{data[0].name}}</p>
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group">
<form action="/update/<%= data[0]._id %>" method="PATCH">
<p style="margin-right:5px;">Disponible: {{data[0].inventory}}</p>
<button type="button" class="btn btn-sm btn-outline-secondary">Agregar al carrito</button>
</form>
</div>

Y tengo un archivo python hello.py que ejecuta el servidor.

from flask import Flask, render_template, redirect, request, url_for
from pymongo import MongoClient
from bson.objectid import ObjectId
app = Flask(__name__)

@app.route('/',methods=['GET'])
def mongoTest():
    client = MongoClient('mongodb://localhost:27017/')
    db = client.ecommerce
    collection = db.items
    results = collection.find()
    # client.close()
    return render_template('base.html', data=results)

@app.route("/update/:id", methods=["PATCH"])
def update_inventory(id):
    client = MongoClient('mongodb://localhost:27017/')
    db = client.ecommerce
    id=request.values.get("id")
    db.items.update_one({ 'id': id}, {'$inc': {'inventory': -1}}, upsert=False)
    results2 = db.items.find()
    return render_template('base.html', data=results2)

if __name__ == '__main__':
    app.run(debug=True)

Sin embargo, no actualiza los valores de inventario.
¿Cómo soluciono este problema?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Hay un par de problemas en el código proporcionado que pueden hacer que los valores del inventario no se actualicen. Aquí hay algunas sugerencias para resolver el problema:

    1. En el archivo HTML, la acción del formulario debe incluir el valor real de id del elemento que se actualizará. Reemplace <%= data[0]._id %> con {{ data[0]._id }} para usar la sintaxis de Jinja2 y obtener el valor.
    2. En la función update_inventory en hello.py, la variable id se asigna dos veces: una vez como parámetro de función y otra vez usando request.values.get("id"). Debe eliminar la segunda línea y usar directamente el parámetro id.

    3. Después de actualizar el elemento en la colección items, la variable results2 no se utiliza en ningún lugar. En lugar de volver a consultar toda la colección, simplemente puedes actualizar los valores de results directamente, ya que se pasa a la plantilla.

    Aquí está el código actualizado:

    base.html:

    <p class="card-text">{{data[0].name}}</p>
    <div class="d-flex justify-content-between align-items-center">
      <div class="btn-group">
        <form action="/update/{{ data[0]._id }}" method="POST">
          <p style="margin-right:5px;">Disponible: {{ data[0].inventory }}</p>
          <button type="submit" class="btn btn-sm btn-outline-secondary">Agregar al carrito</button>
        </form>
      </div>
    </div>
    

    hello.py:

    from flask import Flask, render_template, request
    from pymongo import MongoClient
    from bson.objectid import ObjectId
    
    app = Flask(__name__)
    
    @app.route('/', methods=['GET'])
    def mongoTest():
        client = MongoClient('mongodb://localhost:27017/')
        db = client.ecommerce
        collection = db.items
        results = collection.find()
        return render_template('base.html', data=results)
    
    @app.route("/update/<id>", methods=["POST"])
    def update_inventory(id):
        client = MongoClient('mongodb://localhost:27017/')
        db = client.ecommerce
        item = db.items.find_one({'_id': ObjectId(id)})
        if item['inventory'] > 0:
            db.items.update_one({'_id': ObjectId(id)}, {'$inc': {'inventory': -1}})
            item['inventory'] -= 1
        return render_template('base.html', data=[item])
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    En el código actualizado:

    1. La acción del formulario se establece en /update/{{ data[0]._id }}, que incluye el valor de id.

    2. La función update_inventory ahora recupera el elemento utilizando su ID con db.items.find_one() y verifica si el valor del inventario es mayor que 0 antes de actualizarlo.

    3. En lugar de consultar la colección nuevamente, se actualiza la variable item y luego se pasa a la plantilla en una lista de un solo elemento.

Comments are closed.