Serverside-programmering, templating og sesjonshåndtering.
Flask er et lettvekts Python-rammeverk for webutvikling. Det er perfekt for å lære backend-utvikling fordi det er enkelt å komme i gang med, men kraftig nok for seriøse applikasjoner.
I dette kapittelet skal vi bygge en backend-applikasjon med Flask som håndterer ruter, templates, skjemaer og sessions.
pip install flaskMinimal Flask-app:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hjem():
return 'Velkommen til min Flask-app!'
if __name__ == '__main__':
app.run(debug=True)Kjør appen:
python app.pyApplikasjonen kjører nå på http://localhost:5000
Nøkkelkonsepter:
- @app.route() definerer URL-ruter
- Funksjonen returnerer innhold til brukeren
- debug=True gir bedre feilmeldinger og auto-reload
from flask import Flask, request
app = Flask(__name__)
# GET (standard)
@app.route('/bruker')
def hent_bruker():
return 'Henter bruker'
# POST
@app.route('/bruker', methods=['POST'])
def opprett_bruker():
data = request.json
return f'Oppretter bruker: {data}'
# PUT
@app.route('/bruker/<int:id>', methods=['PUT'])
def oppdater_bruker(id):
return f'Oppdaterer bruker {id}'
# DELETE
@app.route('/bruker/<int:id>', methods=['DELETE'])
def slett_bruker(id):
return f'Sletter bruker {id}'URL-parametere:
@app.route('/produkt/<int:produkt_id>')
def vis_produkt(produkt_id):
return f'Viser produkt {produkt_id}'
@app.route('/bruker/<string:brukernavn>')
def vis_bruker(brukernavn):
return f'Bruker: {brukernavn}'
# Query-parametere: /sok?q=flask
@app.route('/sok')
def sok():
query = request.args.get('q', '')
return f'Søker etter: {query}'Prosjektstruktur:
mitt-prosjekt/
├── app.py
├── templates/
│ ├── base.html
│ ├── hjem.html
│ └── produkt.html
└── static/
├── style.css
└── script.jsTemplates må ligge i mappen "templates"
Sende data til template:
from flask import render_template
@app.route('/velkomst/<navn>')
def velkomst(navn):
return render_template('velkomst.html', brukernavn=navn)Template (velkomst.html):
<!DOCTYPE html>
<html>
<head>
<title>Velkommen</title>
</head>
<body>
<h1>Hei, {{ brukernavn }}!</h1>
</body>
</html><h1>{{ tittel }}</h1>
<p>{{ beskrivelse }}</p>Løkker:
<ul>
{% for produkt in produkter %}
<li>{{ produkt.navn }} - {{ produkt.pris }} kr</li>
{% endfor %}
</ul>Betingelser:
{% if bruker_innlogget %}
<p>Velkommen tilbake!</p>
{% else %}
<p>Vennligst logg inn</p>
{% endif %}Template-arv (base.html):
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}Min side{% endblock %}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<nav>
<a href="/">Hjem</a>
<a href="/om">Om</a>
</nav>
{% block content %}{% endblock %}
<footer>© 2025 Min App</footer>
</body>
</html>Child template (hjem.html):
{% extends "base.html" %}
{% block title %}Hjemmeside{% endblock %}
{% block content %}
<h1>Velkommen!</h1>
<p>Dette er innholdet.</p>
{% endblock %}<form method="POST" action="/send-melding">
<input type="text" name="navn" placeholder="Ditt navn" required>
<input type="email" name="epost" placeholder="Din e-post" required>
<textarea name="melding" placeholder="Din melding" required></textarea>
<button type="submit">Send</button>
</form>Flask route for å håndtere skjema:
from flask import Flask, render_template, request, redirect, url_for, flash
@app.route('/kontakt')
def kontakt():
return render_template('kontakt.html')
@app.route('/send-melding', methods=['POST'])
def send_melding():
navn = request.form.get('navn')
epost = request.form.get('epost')
melding = request.form.get('melding')
# Validering
if not navn or not epost or not melding:
flash('Alle felt må fylles ut', 'error')
return redirect(url_for('kontakt'))
# Lagre melding (database, e-post, etc.)
print(f'Mottatt melding fra {navn} ({epost}): {melding}')
flash('Melding sendt!', 'success')
return redirect(url_for('kontakt'))Flash-meldinger krever secret key:
app.secret_key = 'din-hemmelige-noekkel-her'Vise flash-meldinger i template:
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category }}">{{ message }}</div>
{% endfor %}
{% endif %}
{% endwith %}Enkel innlogging:
from flask import Flask, session, redirect, url_for, request, render_template
app = Flask(__name__)
app.secret_key = 'supersecretkey123'
# "Database" (hardkodet for eksempel)
BRUKERE = {
'admin': 'passord123',
'ola': 'test456'
}
@app.route('/')
def hjem():
if 'brukernavn' in session:
return f'Logget inn som: {session["brukernavn"]} <a href="/logout">Logg ut</a>'
return 'Du er ikke logget inn. <a href="/login">Logg inn</a>'
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
brukernavn = request.form['brukernavn']
passord = request.form['passord']
if brukernavn in BRUKERE and BRUKERE[brukernavn] == passord:
session['brukernavn'] = brukernavn
return redirect(url_for('hjem'))
else:
return 'Ugyldig brukernavn eller passord'
return '''
<form method="post">
<input type="text" name="brukernavn" placeholder="Brukernavn">
<input type="password" name="passord" placeholder="Passord">
<button type="submit">Logg inn</button>
</form>
'''
@app.route('/logout')
def logout():
session.pop('brukernavn', None)
return redirect(url_for('hjem'))Viktig:
- Sessions lagres i cookies (kryptert med secret_key)
- ALDRI hardkod passord i produksjon - bruk bcrypt/hashing
- Secret key bør hentes fra miljøvariabler
Nå skal du løse oppgaver om Flask, ruter, templates og sessions.
Oppsummering
I dette kapittelet har du lært:
- Backend med Flask: serverlogikk i Python.
- Ruter og URL-parametere: håndtere ulike foresporsler.
- Jinja2: templatemotor for dynamiske sider.
- Skjemaer og POST-data: motta data fra brukeren.
- Sessions: brukerautentisering og tilstand.
Noekkelbegreper
| Begrep | Forklaring |
|---|---|
| Backend | Serversiden av en applikasjon |
| Jinja2 | Flask sin templatemotor |
| Session | Lagrer brukertilstand mellom foresporsler |
Oppgaver
Dette kapitlet er skrevet av Anthropics toppmodeller (Claude Opus og Claude Fable) og er foreløpig ikke manuelt gjennomgått — kvalitetskontrollen gjøres av uavhengige KI-agenter, og innmeldte feil rettes fortløpende. Funnet en feil? Meld fra, så retter vi den. Les mer om hvordan innholdet lages.