Da eine neue Sprache nicht genug ist, besch├Ąftige ich mich neben Ruby neuerdings auch noch mit Python.

Als Lernprojekt setze ich aktuell CodrPress als Python-Version um. Nat├╝rlich will ich das nicht das Rad neu erfinden, daher setze ich auf zwei Frameworks, dank denen ich sehr schnell ein vorzeigbares Ergebnis zusammenbauen konnte:

  • Flask ist ein Micro-Framework vergleichbar mit Sinatra (Ruby) oder Silex (PHP). Es k├╝mmert sich also um alles, was man braucht, um eine Website zu bauen. Vom Routing bis hin zur Template Engine (Jinja2).

  • MongoEngine bietet einen ODM (Object Document Mapper) vergleichbar mit Mongoid (Ruby) oder meinem eigenen Projekt MongoAppKit in PHP.

Routen-Definitionen mit Flask

from flask import Flask

app = Flask(__name__)

@app.route('/hello/<name>')
def hello(name):
    return 'Hello %s!' % name

app.run()

Zu Beginn wird die Klasse Flask aus dem Package flask importiert und anschlie├čend eine Instanz erstellt.

Im Gegensatz zu PHP oder anderen C-Syntax-Sprachen kennt Python das Schl├╝sselwort new nicht. Um ein neues Objekt zu instanziieren reicht es den Klassennamen samt den Klammern und ggf. den Constructor-Argumenten zu schreiben.

Es folgt die Routen-Definition. Variable Werte werden in spitze Klammern gesetzt und der anschlie├čenden Methode mit gleichem Namen als Parameter ├╝bergeben.

Wie auch in Silex oder Sinatra wird der R├╝ckgabewert einer Routen-Methode zur├╝ck an den Browser geschickt. In diesem Fall ist das nur ein simpler String-Wert.

Templates in Flask

Flask nutzt die Template Engine Jinja2. Wer aus der PHP-Welt Twig kennt f├╝hlt sich sofort heimisch. Die Sprachelemente sind nahezu identisch.

Datei: ./templates/hello.html

<h1>Hello {{ name }}!</h1>  

In obiger Route m├╝sste die Methode nun so aussehen:

from flask import Flask, render_template
...
def hello(name):
    return render_template('hello.html', name = name)
...

Nicht vergessen: render_template muss zus├Ątzlich importiert werden!

MongoEngine

from mongoengine import *

connect('test')

class Post(Document):
    _id = ObjectIdField()
    created_at = DateTimeField()
    published = BooleanField()
    title = StringField()
    body = StringField()

Der Aufruf von connect stellt eine Verbindung zur Datenbank test her. Da keine Verbindungsdaten angegeben werden, geht MongoEngine automatisch von einem lokalen MongoDB-Server auf dem Standard-Port aus.

Die Klasse Post ist eine Sub-Klasse von Document aus MongoEngine. Anschlie├čend werden die Felder der Klasse definiert. MongoEngine stellt f├╝r jeden von MongoDB unterst├╝tzten Datentyp entsprechende Klassen zur Verf├╝gung.

Sofern nicht ├╝ber das Attribut meta eine andere Collection definiert wird, greift MongoEngine auf den Klassennamen in Kleinbuchstaben als Collection zu.

Um ein neues Dokument von Post zu erstellen und zu speichern, reicht schon folgender Code:

post = Post()
post.published = True
post.title = 'Hello World!'
post.body = 'Hallo, ich ein Test.'
post.save()

Abfragen mit MongoEngine

Als vollst├Ąndiger ODM bietet MongoEngine nat├╝rlich auch die M├Âglichkeit vorhandene Daten abzufragen. In folgendem Beispiel werden die letzten zehn ver├Âffentlichten Eintr├Ąge absteigend nach der Erstelldatum sortiert, in ein Array geschrieben.

posts = Post.objects(published = True).order_by('-created_at').limit(10)

Abfragen erfolgen statisch, daher ist keine Instanz n├Âtig. Die Methode objects() enth├Ąlt die Bedingungen, also in diesem Fall, dass ein Eintrag ver├Âffentlicht wurde. order_by() erwartet den Feldnamen mit der Sortierrichtung als Pr├Ąfix. Hierbei steht + f├╝r aufsteigend und - f├╝r absteigend. Zu guter letzt wird das Ergebnis mit limit() auf 10 Dokumente eingeschr├Ąnkt.

Mit diesem Wissen l├Ąsst sich nun ganz schnell eine Basis-Applikation bauen, die aus der vorhandenen CodrPress-Collection Eintr├Ąge ausliest und anzeigt.

Der bisherige Stand ist nat├╝rlich bei GitHub.