Skip to main content

Endpoint

GET /eliminar/<id>
Deletes a specific vehicle registration record from the CSV database and removes the associated image file from the uploads/ directory.

Path Parameters

id
string
required
The unique identifier of the record to delete. This corresponds to the id field in the CSV database.

Request Flow

  1. Reads all records from data/registros.csv
  2. Filters out the record matching the specified ID
  3. Locates the associated image file
  4. Deletes the image file from uploads/ directory if it exists
  5. Writes the filtered records back to the CSV file
  6. Redirects to the records page with a success message

Response

The endpoint returns an HTTP 302 redirect to the records page (/registros) with a flash message. Status Code: 302 Found Location: /registros Flash Message: Registro eliminado correctamente (category: ok)

Source Code Implementation

@app.route("/eliminar/<id>")
def eliminar(id):
    rows = read_csv()
    filtered = [r for r in rows if r["id"] != id]
    deleted = [r for r in rows if r["id"] == id]
    if deleted:
        img = deleted[0]["imagen"]
        img_path = os.path.join(UPLOADS_DIR, img)
        if os.path.exists(img_path):
            os.remove(img_path)
    write_csv(filtered)
    flash("Registro eliminado correctamente", "ok")
    return redirect(url_for("registros"))

Request Examples

# Delete record with ID 5
curl http://localhost:5000/eliminar/5

Deletion Process Details

Step 1: Filter Records

The endpoint creates two lists:
  • filtered: All records except the one to delete
  • deleted: The record(s) matching the ID (typically 0 or 1)

Step 2: Image Removal

If a matching record is found:
  1. Extract the imagen field (filename)
  2. Construct full path: uploads/<filename>
  3. Check if file exists using os.path.exists()
  4. Remove file using os.remove()

Step 3: CSV Update

The filtered records are written back to the CSV file, effectively removing the deleted record.

Important Behaviors

No Confirmation: This endpoint does not ask for confirmation. Deletion is immediate and irreversible. Implement client-side confirmation dialogs for safety.
ID Comparison: The ID comparison uses string matching (r["id"] != id). IDs are treated as strings, not integers.
Missing Images: If the associated image file doesn’t exist (already deleted or moved), the endpoint still succeeds and removes the record from the CSV.
Non-existent IDs: If the specified ID doesn’t exist, the endpoint still returns success without any error. No records are deleted, and no error message is shown.

Error Scenarios

Scenario 1: Record Not Found

If you try to delete a non-existent record ID:
  • No records are removed from the CSV
  • No error is thrown
  • Success message is still displayed
  • User is redirected to /registros

Scenario 2: Image File Missing

If the CSV record exists but the image file is missing:
  • Record is removed from CSV
  • No error occurs (file existence is checked first)
  • Success message is displayed

Scenario 3: CSV File Locked

If another process has the CSV file locked:
  • File I/O error may occur
  • This would result in a 500 error (not handled gracefully)

Security Considerations

No Authentication: Any user can delete any record by knowing its ID. Implement authentication and authorization for production use.
ID Enumeration: Sequential IDs make it easy to enumerate and delete all records. Consider using UUIDs for production.
Directory Traversal: The current implementation is safe because the image filename comes from the database, not user input. However, ensure validation if this changes.
For production use, consider:
  1. Use DELETE method instead of GET:
    @app.route("/eliminar/<id>", methods=["DELETE"])
    
  2. Return JSON for API responses:
    return jsonify({"success": True, "message": "Record deleted"}), 200
    
  3. Add soft deletes (mark as deleted instead of removing):
    record["deleted_at"] = datetime.now().isoformat()
    
  4. Implement validation:
    if not deleted:
        flash("Registro no encontrado", "error")
        return redirect(url_for("registros"))
    

Sample Deletion Flow

Before Deletion - CSV contains:
id,fecha_hora,matricula,propietario,tipo_vehiculo,observacion,imagen
1,2026-03-04 15:30:45,ABC1234,Juan Pérez,Sedan,Vehículo de entrega,matricula_20260304_153045.jpg
2,2026-03-04 16:15:22,XYZ5678,María García,SUV,Acceso autorizado,matricula_20260304_161522.jpg
3,2026-03-04 17:20:10,DEF9012,Carlos López,Motorcycle,,matricula_20260304_172010.jpg
Request: GET /eliminar/2 After Deletion - CSV contains:
id,fecha_hora,matricula,propietario,tipo_vehiculo,observacion,imagen
1,2026-03-04 15:30:45,ABC1234,Juan Pérez,Sedan,Vehículo de entrega,matricula_20260304_153045.jpg
3,2026-03-04 17:20:10,DEF9012,Carlos López,Motorcycle,,matricula_20260304_172010.jpg
File Deleted: uploads/matricula_20260304_161522.jpg

View Records

See all records before deleting

Upload Plate

Add new records

Download CSV

Backup data before bulk deletions

Build docs developers (and LLMs) love