23 Haziran 2014 Pazartesi

Flask ile Blog Uygulaması





Önceki yazımda Flask'ın kurulumunu anlatmıştım. Şimdi Flask kullanarak basitçe bir blog nasıl yazılır adım adım anlatmaya çalışacağım.

  $ mkdir flaskr
  $ cd flaskr
  $ vim schema.sql

  Açılan dosya içine şu satırları ekleyelim:

  drop table if exists entries;
  create table entries (
          id integer primary key autoincrement,
          title text not null,
          text text not null
   );

  Kaydedip çıkalım. Database olarak sqlite3 kullanacağız. Yukarıda blog bilgilerimizi ( id, başlık, gövde ) tutacak basit bir tablo oluşturmak için kullanacağımız dosyayı yazdık. id bilgisi primary key dir ve otomatik olarak artar. Devam edelim.

  $ vim flaskr.py

  Açtığımız dosyaya şu satırları ekliyoruz:

  # Gerekli modülleri dahil ettik
  import os
  import sqlite3
  from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash

  # app adında küçük bir uygulama oluşturduk.
  app = Flask(__name__)
  app.config.from_object(__name__)

  # Uygulama için gerekli yapılandırma bilgilerini ekledik.
  app.config.update(dict(
          DATABASE='/tmp/flaskr.db',
          DEBUG=True,
          SECRET_KEY=’development key’,
          USERNAME=’admin’,
          PASSWORD=’default’
  ))
  app.config.from_envvar(’FLASKR_SETTINGS’, silent=True)

# Özel bir veritabanına bağlantı yapmak için     def connect_db():
          rv = sqlite3.connect(app.config[’DATABASE’])
          rv.row_factory = sqlite3.Row
          return rv

# Veritabanı bağlantısı için gerekli kısım.
  def get_db():
  if not hasattr(g, ’sqlite_db’):
          g.sqlite_db = connect_db()
   return g.sqlite_db

  @app.teardown_appcontext
  def close_db(error):
  if hasattr(g, ’sqlite_db’):
          g.sqlite_db.close()

  # Veritabanını başlatacak kısım
  def init_db():
          with app.app_context():
                  db = get_db()
                  with app.open_resource(’schema.sql’, mode=’r’) as f:
                          db.cursor().executescript(f.read())
                  db.commit()

  # Yazılmış olan blog yazılarını ve başlıklarını görüntüleyecek kısım.
  @app.route(’/’)
  def show_entries():
          db = get_db()
          cur = db.execute(’select title, text from entries order by id desc’)
          entries = cur.fetchall()
          return render_template(’show_entries.html’, entries=entries)

  # Yeni bir blog girdisinin veritabanına girişini sağlayan kısım.
  @app.route(’/add’, methods=[’POST’])
  def add_entry():
          if not session.get(’logged_in’):
                  abort(401)
          db = get_db()
          db.execute(’insert into entries (title, text) values (?, ?)’, [request.form[’title’], request.form[’text’]])
          db.commit()
          flash(’New entry was successfully posted’)
          return redirect(url_for(’show_entries’))

  # Giriş yapmayı sağlayan kısım
  @app.route(’/login’, methods=[’GET’, ’POST’])
  def login():
          error = None
          if request.method == ’POST’:
                  if request.form[’username’] != app.config[’USERNAME’]:
                          error = ’Invalid username’
                  elif request.form[’password’] != app.config[’PASSWORD’]:
                          error = ’Invalid password’
                  else:
                          session[’logged_in’] = True
                          flash(’You were logged in’)
                          return redirect(url_for(’show_entries’))
          return render_template(’login.html’, error=error)


  # Çıkış yapmayı sağlayan kısım
  @app.route(’/logout’)
  def logout():
          session.pop(’logged_in’, None)
          flash(’You were logged out’)
          return redirect(url_for(’show_entries’))

  # Uygulamayı başlatan kısım
  if __name__ == ’__main__’:
          app.run()

    Bu dosyayı kaydedip çıkıyoruz. Komut satırında veri tabanınındaki tablomuzun oluşması için şu komutu  veriyoruz:

  $ sqlite3 /tmp/flaskr.db < schema.sql

  Veri tabanını başlatmak için python kabuğunda şu komutları veriyoruz:

  $ python
  >>> from flaskr import init_db
  >>> init_db()


  Şimdi gereken şablonları ekleyelim:

  $ mkdir templates
  $ cd templates
  $ vim layout.html

  Açılan dosyaya şu satırları ekleyelim:

  <!doctype html>
 <title>Flaskr</title>
 <link rel=stylesheet type=text/css href="{{ url_for(’static’, filename=’style.css’) }}">
 <div class=page>
   <h1>Flaskr</h1>
     <div class=metanav>
     {% if not session.logged_in %}
       <a href="{{ url_for(’login’) }}">log in</a>
     {% else %}
       <a href="{{ url_for(’logout’) }}">log out</a>
     {% endif %}
     </div>
     {% for message in get_flashed_messages() %}
       <div class=flash>{{ message }}</div>
     {% endfor %}
     {% block body %}{% endblock %}
   </div>

  Kaydedip çıkalım. Blog girdilerini göstermek için bir şablon ekleyelim

  $ vim show_entries.html

  Açılan dosyaya şu satırları ekleyelim:

  {% extends "layout.html" %}
  {% block body %}
    {% if session.logged_in %}
       <form action="{{ url_for(’add_entry’) }}" method=post class=add-entry>
       <dl>
         <dt>Title:
           <dd><input type=text size=30 name=title>
         <dt>Text:
           <dd><textarea name=text rows=5 cols=40></textarea>
           <dd><input type=submit value=Share>
       </dl> 
     </form>
  {% endif %}
  <ul class=entries>
  {% for entry in entries %}
     <li><h2>{{ entry.title }}</h2>{{ entry.text|safe }}
  {% else %}
     <li><em>Unbelievable. No entries here so far</em>
  {% endfor %}
   </ul>
{% endblock %}

  Kaydedip çıkalım. Şimdi giriş için bir şablon ekleyelim:

  $ vim login.html

  Açılan dosyaya şunları ekleyelim:

  {% extends "layout.html" %}
  {% block body %}
    <h2>Login</h2>
    {% if error %}<p class=error><strong>Error:</strong> {{ error }}{% endif %}
     <form action="{{ url_for(’login’) }}" method=post>
       <dl>
         <dt>Username:
           <dd><input type=text name=username>
        <dt>Password:
          <dd><input type=password name=password>
        <dd><input type=submit value=Login>
      </dl>
    </form>
  {% endblock %}

 Kaydedip çıkalım. Şimdi görünümü iyileştirmek için css dosyası ekleyeceğiz. 

 $ cd ..
 $ mkdir static
 $ cd static
 $ vim style.css

 Açılan dosya içine şunları ekleyelim: 

 body            { font-family: sans-serif; background: #eee; }
 a, h1, h2       { color: #377ba8; }
 h1, h2          { font-family: ’Georgia’, serif; margin: 0; }
 h1              { border-bottom: 2px solid #eee; }
 h2              { font-size: 1.2em; }

 .page           { margin: 2em auto; width: 35em; border: 5px solid #ccc; padding: 0.8em;  background: white; }
 .entries        { list-style: none; margin: 0; padding: 0; }
 .entries li     { margin: 0.8em 1.2em; }
 .entries li h2  { margin-left: -1em; }
 .add-entry      { font-size: 0.9em; border-bottom: 1px solid #ccc; }
 .add-entry dl   { font-weight: bold; }
 .metanav        { text-align: right; font-size: 0.8em; padding: 0.3em; margin-bottom: 1em;  background: #fafafa; }
 .flash          { background: #cee5F5; padding: 0.5em; border: 1px solid #aacbe2; }
 .error          { background: #f0d6d6; padding: 0.5em; }


  Dosyayı kaydedip çıkabiliriz. 


  Şimdi flaskr.py dosyasının olduğu dizine geçelim ve uygulamayı çalıştıralım

  $ cd ..
  $ python flaskr.py

  Komut satırında karşımıza çıkan url yi tarayıcıya yazarak uygulamanın nasıl çalıştığını görebiliriz.