My Flask Hiccups

Developed small application with the help of flask. in the process encountered few issues,recording here if somebody benefit from this.

1. Getting values from forms

  1. To check methos id GET or POST
    if request.method == ‘GET’:
  2. To get values from “form”
  • request.form.get(‘team’, “”) request.form.get(‘team’, none)

3. To get the list of values. for instance you have something like this ```<select multiselect=””multiselect>`` and user can choose mutiple values.
 Just ensure you have name segement in ```<select multiselect=””multiselect name=”developers”>``` and access the same

```request.form.getlist(‘developers’):
 ```

2. Misunderstadining with redirect

Good thing with flask design is we do not have too many ways to send response back to client unlike django. Either you have #redirect# or rendering atemplate with render_template(‘index.html’, teams=get_teams())

Redirect with generally we assume that url_for is at times very misleading generally we assume that url_for(XXXXX) that XXXX we assume that it is route. in fact it is not a route name it is the function name underlying the route in question

redirect(url_for(‘index’))

You can even pass parameter to url_for(‘index’, XXXX). XXXX is based to underlying view

3. Multiple routes with defaults, defaults has different meaning

Assuming you want to refer to same function under different routes but you want to supply few default values a route. Here is misconception that you are not supplying to rote or nothing gets added to route but “DEFAULTS” will be supplied to underlying view. Default will not change “routes” anyway but they only supply defaults to views.

@app.route('/teams/<team_name>', defaults={'status': 'ALL'})
@app.route('/teams/<team_name>/<status>')
def team_page(team_name, status):
pass

in the above example only status=ALL in the underlying view when you call http://localhost:5000/teams/XYZ

4. Accessing database.

If you are using sqlalchemy you can directly query them but some of them are difficult write through sqlaclhemy.

  1. if you already defined model and wants to load all the rows or wants filter them directly is ORM way
  2. PullRequest.query.filter_by(team=team_name)
  3. Soemtimes it si diffuclt query through ORM, you may end up directly querying like below
  4. result = db.engine.execute(“select distinct(team_name) from team”) teams = [] for row in result: teams.append(row[0])
  5. here we need to remember that when you excute query directly you can’t access the rows column directly as you do on ORM. row is literally database row and columns you need to access based on its position. Bit a pain but sometimes it is easy to do that as sqlalchemy is kind of complex to master.

5. Referencing Static resources .

To reference static resources use belwo links.It is more to do with Jinja2 than flask.But flask ,default,supports junja2 templates.

1. link stylesheet
  <link rel="stylesheet" href="{{ url_for('static', filename='main.css') }}">
 2. link java script
  <script type="text/javascript" src="{{ url_for('static', filename='multiselect.js') }}"></script>
 3. extending base template
    {% extends "base.html" %}
{% block content %}
{% endblock %}
 4. including partials
   {% include 'navbar.html' %}
 5. loops ,conditionals
    for :
{% for team in teams %}
<a href="/teams/{{team}}" class="list-group-item"><b>{{ team }}</b></a>
{% endfor %}
    if:
    {% if record.status == 'XX' %}
<tr class="success">
{% elif record.status == 'YY' %}
<tr class="danger">
{% else %}
<tr class="info">
{% endif %}

6. Where do you want to place your db instace.

db = SQLAlchemy()

  1. This is crucial, if you are using SQLAlchemy. It makes sense to place it in models.py,preferabley you can create similar of base_models.py and create a base model class for all the DB models that you plan to create.
class Base(db.Model):
    __abstract__  = True
    id            = db.Column(db.Integer, primary_key=True)
create_at = db.Column(db.DateTime, default=db.func.current_timestamp())
updated_at = db.Column(db.DateTime, default=db.func.current_timestamp(),
onupdate=db.func.current_timestamp())

However db initiation must be done in app.py or app package if you have ini.py in the folder

#app.py
from models import db
db.init_app(app)

Reference : https://www.digitalocean.com/community/tutorials/how-to-structure-large-flask-applications

7. deployment issues.

Default app.run will service only one instance /one user.To service mutiple users try using gunicorn. install gunicorn as it is WSGI application server which is capable of serving multple instances. just pip install gunicorn.

gunicorn -w 5 -b 127.0.0.1:9000 app:app&

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.