Aplicación con citas
De WikiEducator
< Usuario:Lmorillas | desarrollo web servidor | flask | ejemplo completo
Revisión a fecha de 19:29 15 nov 2013; Lmorillas (Discusión | contribuciones)
Contenido
Modelo
class Cita(Base): """Una cita en el calendario.""" __tablename__ = 'cita' id = Column(Integer, primary_key=True) creada = Column(DateTime, default=datetime.now) modificada = Column(DateTime, default=datetime.now, onupdate=datetime.now) evento = Column(String(255)) inicio = Column(DateTime, nullable=False) fin = Column(DateTime, nullable=False) todoeldia = Column(Boolean, default=False) lugar = Column(String(255)) descripcion = Column(Text) user_id = Column(Integer, ForeignKey('usuarios.id'), nullable=False) usuario = relationship(User, lazy='joined', join_depth=1, viewonly=True) def duracion(self): tiempo = self.fin - self.inicio return tiempo.days * 24 * 60 * 60 + tiempo.seconds def __str__(self): return "{evento} [{fecha}}".format(evento=self.evento, fecha=self.inicio)
Listado de citas
Controlador
@app.route('/citas/') @login_required def lista_citas(): """Lista de todas las citas en la base de datos.""" # Query: Recupera las citas del usuario, ordenadas por fecha. citas = (db.session.query(Cita) .filter_by(user_id=session['uid']) .order_by(Cita.inicio.asc()).all()) return render_template('cita/index.html', citas=citas)
Tempate
Macro auxiliar
{% macro detalle(cita) %} <div class="detalle-cita"> <h3>{{ cita.evento or '(sin titulo)' }}</h3> {% if cita.lugar %}<p><i class="icon-home"></i> {{ cita.lugar }}</p>{% endif %} {% if cita.todoeldia %} <p><i class="icon-calendar"></i> {{ cita.inicio }}</p> {% else %} <p><i class="icon-calendar"></i> {{ cita.inicio }}. Duración: {{ cita.duracion() }}</p> {% endif %} </div> {% endmacro %}
cita/index.html'
{% extends 'layout.html' %} {% from 'cita/comun.html' import detalle %} {% block content %} <div class="row"> {% for cita in citas %} <div class="cita"> {{ detalle(cita) }} </div> {% else %} <h3 class="span12">No hay citas.</h3> {% endfor %} </div> {% endblock content %}
Creación de nuevas citas
Controlador
@app.route('/cita/crear/', methods=['GET', 'POST']) @login_required def crear_cita(): """Muestra el formulario para crear una cita""" form = FormCita(request.form) if request.method == 'POST' and form.validate(): cita = Cita(user_id=session['uid']) form.populate_obj(cita) db.session.add(cita) db.session.commit() # Exito: devuelve al usuario a la lista de citas return redirect(url_for('lista_citas')) # Error o GET. return render_template('cita/editar.html', form=form)
Formulario
class FormCita(Form): """Formulario para el modelo Citas. Genera HTML y valida entradas """ titulo = TextField('Cita', [validators.Length(max=255)]) inicio = DateTimeField('Inicio', [validators.Required()]) fin = DateTimeField('Fin') todoeldia = BooleanField('Todo el día') lugar = TextField('Lugar', [validators.Length(max=255)]) descripcion = TextAreaField('Descripción')
Template
{% extends "layout.html" %} {% block content %} <h2>Crear Cita</h2> {% for message in form.titulo.errors %} <div class="flash">{{message }}</div> {% endfor %} {% for message in form.inicio.errors %} <div class="flash">{{ message }}</div> {% endfor %} {% for message in form.fin.errors %} <div class="flash">{{ message }}</div> {% endfor %} <form action="{{ url_for('crear_cita') }}" method=post> {{ form.hidden_tag() }} {{ form.titulo.label }} {{ form.titulo }} {{ form.inicio.label }} {{ form.inicio }} {{ form.fin.label }} {{ form.fin }} {{ form.todoeldia.label }} {{ form.todoeldia}} {{ form.lugar.label }} {{ form.lugar}} {{ form.descripcion.label }} {{ form.descripcion}} {{ form.crear }} </form> {% endblock %}
Mostrar el detalle de una cita
@app.route('/cita/<int:cita_id>/') @login_required def detalle_cita(cita_id): """Detalle de una cita dada.""" # Query: obtiene el objeto por ID cita = db.session.query(Cita).get(cita_id) if cita is None or cita.user_id != session.uid: # Abortar con Not Found. abort(404) return render_template('cita/detalle.html', cita=cita)
Editar cita existente
@app.route('/citas/<int:cita_id>/editar/', methods=['GET', 'POST']) @login_required def editar_cita(cita_id): """Prepara el formulario HTML para editar una cita.""" cita = db.session.query(Cita).get(cita_id) if cita is None: abort(404) if cita.user_id != session[uid]: abort(403) form = FormCita(request.form, cita) if request.method == 'POST' and form.validate(): form.populate_obj(cita) db.session.commit() # Si hay éxito, vuelve a la vista de detalle de la cita return redirect(url_for('detalle_cita', cita_id=cita.id)) return render_template('cita/edit.html', form=form)