Django

Všichni určitě máme rádi Python a kdo ne, ten Python nejspíš pořádně nikdy nevyzkoušel. Tento snadno naučitený jazyk, není nutně jen shell jazykem pro skriptovaní, ale může nalézt uplatnění i jinde, například pro vývoj jednoduchých a rychlých webů. Nebo často také pro tvorbu specializovaných webů v Django/Flask frameworku.

Naše první aplikace ve Flasku, nainstalujeme pip3 a flask:

apt-get install python3-pip
pip3 install flask flask-sqlalchemy

Napíšeme základní kód aplikace pro Flask:

app.py
from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "<h1 style='color:blue'>Hello There!</h1>"

if __name__ == "__main__":
    # IPv4
    #app.run(host='0.0.0.0', port=8000, debug=True)
    # IPv6
    app.run(host='::', port=8000, debug=True)

A spustíme aplikaci:

python3 app.py

Pro používaní template do kódu přidáme render_template. Na servírováni statického obsahu pro css vložíme url_for. Hlavním motivem pro templatovaní je, že ke změně kódu na více stránkách nám bude stačit udělat relativně malé změny, převážně na jednom místě.

app.py
from flask import Flask
from flask import Flask, render_template, url_for
app = Flask(__name__)

@app.route("/")
def hello():
    return render_template('index.html')

if __name__ == "__main__":
    #app.run(host='0.0.0.0', port=8000, debug=True)
    app.run(host='::', port=8000, debug=True)

Vytvoříme statické adresáře a soubory static/css/main.css, a adresář templates/{base.html, index.html}:

templates/index.html
{% extends 'base.html' %}

{% block head %}
<title>Flask example</title>
{% endblock %}

{% block body %}
<h1>FLASK - BODY</h1>
<p>Flask je Python framework</p>
{% endblock %}
templates/base.html
<!DOCTYPE html>
<html lang="en">

<head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta name="description" content="yono.cz tutorial">
        <meta name="keywords" content="Python, Linux">
        <meta name="author" content="Zden2k">

        <link href="{{ url_for('static', filename='css/main.css') }}" rel="stylesheet">

        {% block head %}{% endblock %}
</head>
<body>
{% block body %}{% endblock %}
</body>
</html>
static/css/main.css
body {
        margin: 0;
        font-family: sans-serif;
}
p {
  color: red;
}

SqlAlchemy je rozšíření Flasku pro práci s Databázemi. Na stránkách Flask-SqlAlechemy je docela povedená dokumentace, jak SqlAlchemy používat, včetně příkladů a různých propojení mezi tabulkami. Příklad ukazuje jak pracovat s tabulkami včetně "Relationships".

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///my.db'
db = SQLAlchemy(app)

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(80), nullable=False)
    body = db.Column(db.Text, nullable=False)
    pub_date = db.Column(db.DateTime, nullable=False,
        default=datetime.utcnow)

    category_id = db.Column(db.Integer, db.ForeignKey('category.id'),
        nullable=False)
    category = db.relationship('Category',
        backref=db.backref('posts', lazy=True))

    def __repr__(self):
        return '<Post %r>' % self.title

class Category(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), nullable=False)

    def __repr__(self):
        return '<Category %r>' % self.name

if __name__ == "__main__":
    #app.run(host='0.0.0.0', port=8000, debug=True)
    app.run(host='::', port=8000, debug=True)

Vytvoříme Databázi a vložíme do ni nějaké články. Práce se SqlAlchemy vypada takto:

#>>> from app import db
#>>> db.create_all()
#>>> from app import Post
#>>> from app import Category
#>>> py = Category(name='Python')
#>>> Post(title='Hello Python!', body='Python is pretty cool', category=py)
#<Post 'Hello Python!'>
#>>> p = Post(title='Snakes', body='Ssssssss')
#>>> py.posts.append(p)
#>>> db.session.add(py)
#>>> db.session.commit()
#>>> py.posts
#[<Post 'Hello Python!'>, <Post 'Snakes'>]
#>>> py.query.all()
#[<Category 'Python'>]
#>>> p.query.all()
#[<Post 'Hello Python!'>, <Post 'Snakes'>]
#>>> Post.query.all()
#[<Post 'Hello Python!'>, <Post 'Snakes'>]
#>>> Category.query.all()
#[<Category 'Python'>]
#>>> post = Post.query.filter_by(title='Snakes').first()
#>>> post.id
#2
#>>> post.title
#'Snakes'
#>>> post.body
#'Ssssssss'
#>>> Post.query.all()
#>>> post = Post.query.first()
#>>> post.id
#1
#>>> post.body
#'Python is pretty cool'
#>>> post.title
#'Hello Python!'
#>>> Post.query.order_by(Post.title).all()
#[<Post 'Hello Python!'>, <Post 'Snakes'>]

Můžeme se podívat přímo do té DB, co se v ní nachází:

#root@django:/home/zsobotka#> sqlite3 my.db 
#SQLite version 3.27.2 2019-02-25 16:06:06
#Enter ".help" for usage hints.
#sqlite> .tables
#category  post    
#sqlite> select * from category
#   ...> ;
#1|Python
#sqlite> select * from post;
#1|Hello Python!|Python is pretty cool|2020-07-06 12:45:52.006885|1
#2|Snakes|Ssssssss|2020-07-06 12:45:52.007162|1
#sqlite> PRAGMA table_info(post);
#0|id|INTEGER|1||1
#1|title|VARCHAR(80)|1||0
#2|body|TEXT|1||0
#3|pub_date|DATETIME|1||0
#4|category_id|INTEGER|1||0

Pokud máme nějakou aplikaci a chceme ji přenést na jiný systém. Určitě se nám bude hodit přenést jí i s balíky, které už má nainstalované v Pythonu, a které jsou nutné pro její funkci.

# install python requirements
python3 -m pip install -r requirements.txt

Obsah souboru requirements.txt může vypadat například takto:

Flask==1.1.2
Flask-Login==0.5.0
Flask-SQLAlchemy==2.4.3
SQLAlchemy==1.3.17

apt-get install python3-venv
python3 -m venv auth
source auth/bin/activate