first off if you're reading this, thank you very much. It's my first time posting here.
I'm a bit new to Flask and Python as a whole.
I'm trying to create a query to check if the user has reserved or not a class. It's pretty straight forward, I have an activity table in mySQL DB with things like name, description, etc. And I have a reserves table. This reserves table has the activity id (id_actividad) (I program in spanish so variables and such are in spanish) and user id (id_usuario) as well as it's own id. Basically, it shows the activities perfectly fine and does the check as well. However, when I try to actually make the reservation, I encounter the following error:
line 258, in reserva_actividad
if Actividades.is_reservado(id_usuario, id_actividad):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Actividades.is_reservado() missing 1 required positional argument: 'id_actividad'
So my code itself is broken down into 3 main parts, Actividades.py where I delcare my class and methods, usuario.py (which is where I'm currently executing) and then actividades.html, which is the template for this particular part. I've tried making the is_reservado class static, taking off the self (oddly, if self is not defined then it doesn't get anything from reservas, just actividades table) but ultimately it doesn't work. I'd appreciate any help or something I'm 100% missing here, I'll leave the relevant fragments of code down below.
Thank you!
Actividades.py:
class Actividades(UserMixin):
def __init__(self, id_actividad, nombre, fecha, hora_inicio, hora_fin, detalles, capacidad) -> None:
self.id_actividad = id_actividad
self.nombre = nombre
self.fecha = fecha
self.hora_inicio = hora_inicio
self.hora_fin = hora_fin
self.detalles = detalles
self.capacidad = capacidad
def is_reservado(self, id_usuario, id_actividad):
try:
con = conexion()
with con.cursor() as cursor:
cursor.execute('SELECT * FROM reservas WHERE id_actividad = %s AND id_usuario = %s', (id_actividad, id_usuario))
reserva = cursor.fetchone()
if reserva:
return True
else:
return False
except Exception as ex:
raise Exception(ex)
usuario.py:
@app.route('/reserva_actividad', methods=['POST'])
def reserva_actividad():
id_actividad = int(request.form['id_actividad'])
print("id_actividad:", id_actividad) # gets it correctly, for example, 3
id_usuario = current_user.get_id()
print("id_usuario:", id_usuario) # also gets it correctly, for example, 22
if Actividades.is_reservado(id_usuario, id_actividad):
# User already has a reservation for this activity, handle accordingly
print("User already has a reservation for this activity")
return "You already have a reservation for this activity"
Actividades.reserva(id_actividad, id_usuario)
return redirect(url_for('actividades'))
actividades.html:
`
{% extends "layouts.html" %}
{% block contentD %}
<style>
.reservado {
color: red;
}
.disponible {
color: green;
}
</style>
<h1>Actividades Disponibles</h1>
<table class="table">
<thead>
<tr>
<th>Nombre</th>
<th>Fecha</th>
<th>Hora de inicio</th>
<th>Hora de fin</th>
<th>Capacidad</th>
<th>Reservada</th>
<th>Acción</th>
</tr>
</thead>
<tbody>
{% for actividad in actividades %}
<tr>
<td>{{ actividad.nombre }}</td>
<td>{{ actividad.fecha }}</td>
<td>{{ actividad.hora_inicio }}</td>
<td>{{ actividad.hora_fin }}</td>
<td>{{ actividad.capacidad }}</td>
{% if actividad.is_reservado(current_user.id, actividad.id_actividad) %}
<td class="reservado">Reservado</td>
{% else %}
<td class="disponible">Disponible</td>
{% endif %}
<td>
{% if not actividad.is_reservado(current_user.id, actividad.id_actividad) %}
<form action="/reserva_actividad" method="POST">
<input type="hidden" name="id_actividad" value="{{ actividad.id_actividad }}">
<button type="submit" class="btn btn-primary">Reservar</button>
</form>
{% else %}
<form action="/cancelar_reserva" method="POST">
<input type="hidden" name="id_actividad" value="{{ actividad.id_actividad }}">
<button type="submit" class="btn btn-danger">Cancelar</button>
</form>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock contentD %}
`
In usuario.py, in the if condition, you are calling the method in a static contect, meaning you're not calling it on an object of class Actividades.
When you're calling the method like Actividades.is_reservado(), you would need to pass the object of type Actividades as a first argument and the id's as second and third. That's why the error message says that one parameter is missing. Of course you could just do object.is_reservado() and pass on only the two arguments.
Examples:
obj = Actividades(...)
Actividades.is_reservado(obj, id_usuario, id_actividad)
obj.is_reservado(id_usuario, id_actividad)
However, seeing as the method is_reservado doesn't use any class properties, it might be a better idea to make it a separate function or just annotate it with @staticmethod and remove the self parameter.
Hope that helped.