Flask學習筆記 - 快速入門/Tutorlal學習/SQLALchemy

Table of Contents

1 Flask快速入門

1.1 WSGI,  web server gateway interface

1.2 A minimal application

2 Flask Tutorial筆記

3 SQLALchemy

參考資料

簡單介紹和案例


1 Flask快速入門

1.1 WSGI,  web server gateway interface

WSGI不是服務器,不是API,不是Python模塊,更不是什麼框架,而是一種服務器和客戶端交互的接口規範

在WSGI規範下,web組件被分成三類:client, server, and middleware.

WSGI apps(服從該規範的應用)能夠被連接起來(be stacked)處理一個request,這也就引發了中間件這個概念,中間件同時實現c端和s端的接口,c看它是上游s,s看它是下游的c。

WSGI的s端所做的工作僅僅是接收請求,傳給application(做處理),然後將結果response給middleware或client.除此以外的工作都交給中間件或者application來做。

1.2 A minimal application

  • Debug mode:
$ export FLASK_DEBUG=1
$ flask run
  • Routing:route() decorator is used to bind a function to URLs.
@app.route('/')
def index():
    return 'Index Page'

@app.route('/hello')
def hello():
    return 'Hello, World'
  • Variables Rules:We can add variable parts to a URL. You can mark these special sections as <variable_name>. Such a part is then passed as a keyword argument to your function. Optionally, a converter can be  used by specifying a rule with <converter:variable_name>.
@app.route('/user/<username>')
def show_user_profile(username):
    # show the user profile for that user
    return 'User %s' % username

@app.route('/post/<int:post_id>')
def show_post(post_id):
    # show the post with the given id, the id is an integer
    return 'Post %d' % post_id

The following converters exist:

string

accepts any text without a slash (the default)

int

accepts integers

float

like int but for floating point values

path

like the default but also accepts slashes

any

matches one of the items provided

uuid

accepts UUID strings

  • Unique URLs/Redirection Behavior
  • Flask's URL rules are based o Werkzeug's routing module. The idea is to ensure beautiful and unique URLs.
@app.route('/projects/')
def projects():
    return 'The project page'

 

In that sense, it is similar to a folder on a filesystem. Accessing it without a trailing slash will cause Flask to redirect to the canonical URL with the trailing slash.

@app.route('/about')
def about():
    return 'The about page'

 

 Like the pathname of a file on UNIX-like systems. Accessing the URL with a trailing slash will produce a 404 “Not Found” error.

  • URL Building
    • url_for(): build a URL to a specific function .
      • url_for(function name, variable part of the URL rule)
      • Noted:  unknown variable parts are appended to the URL as query parameters.
    • Test_request_context(): tells Flask to behave as though it is handling a request, even though we are interacting with it through a Python shell. 
    • Why using url_for()?
      • Reversing is often more descriptive than hard-coding the URLs. More importantly, it allows you to change URLs in one go, without having to remember to change URLs all over the place.
      • URL building will handle escaping of special characters and Unicode data transparently for you, so you don’t have to deal with them.
      • If your application is placed outside the URL root - say, in /myapplication instead of / - url_for() will handle that properly for you.
  • HTTP Methods

Route() : can also provide the HTTP method argument.

from flask import request

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        do_the_login()
    else:
        show_the_login_form()
  •  Reference - HTTP
    • HTTP tells the server what the client want to do with the requested page. There are some common methods used by HTTP:
      • GET: The browser tells the server to just get the information stored on that page and send it. This is probably the most common method
      • HEAD: The browser tells the server to get the information, but it is only interested in the headers, not the content of the page. An application is supposed to handle that as if a GET request was received but to not deliver the actual content. In Flask you don’t have to deal with that at all, the underlying Werkzeug library handles that for you.
      • POST: The browser tells the server that it wants to post some new information to that URL and that the server must ensure the data is stored and only stored once. This is how HTML forms usually transmit data to the server.
      • PUT: Similar to POST but the server might trigger the store procedure multiple times by overwriting the old values more than once. Now you might be asking why this is useful, but there are some good reasons to do it this way. Consider that the connection is lost during transmission: in this situation a system between the browser and the server might receive the request safely a second time without breaking things. With POST that would not be possible because it must only be triggered once.
      • DELETE: Remove the information at the given location.
      • OPTIONS: Provides a quick way for a client to figure out which methods are supported by this URL. Starting with Flask 0
  • Static files
  • Rendering Templates: render_template(template_name, variables you want to pass to the template engine as keyword arguments)

Inside templates, you also have access to the request, session and g objects as well as the get_flashed_messages() function.

from flask import render_template

@app.route('/hello/')
@app.route('/hello/<name>')
def hello(name=None):
    return render_template('hello.html', name=name)
  • Accessing Request Data - Context locals
  • The request object:From flask import request
  • File uploads
    • 確保你沒忘記在 HTML 表單中設置enctype="multipart/form-data" 屬性
  • Cookies
    • Set_cookie()
  • Redirect and error:To redirect a user to another endpoint, use the redirect() function; to abort a request early with an error code, use the abort() function:
  • Session:除請求對象之外,還有一個 session 對象。它允許你在不同請求間存儲特定用戶的信息。它是在 Cookies 的基礎上實現的,並且對 Cookies 進行密鑰簽名。這意味着用戶可以查看你 Cookie 的內容,但卻不能修改它,除非用戶知道簽名的密鑰。

2 Flask Tutorial筆記

  • 1. Create the folders

Static folder:  are avaliable to users of application via HTTP. This is the place where CSS and javascript files go.

Templates Folder: where flask will look for Jinja2 templates

  • 2. Database schema

Create a file named schema.sql in the flaskr/flaskr folder

The contents of the schema.sql are as follows:

Introduction: this consists of a single table called entries.

  • 3. Application setup code
  • 4. Database connection
    • Flask provides two contexts, the application context and the request context. There are special variables that use these. For instance, the request variable is the request object associated with the current request context, whereas g is a general purpose variable associated with the current application context. You can store information safely on the g object.
    • Functions marked with teardown_appcontext() are called every time the application context tears down. The application context is created before the request comes in and is destroyed (torn down) whenever the request finishes. A teardown can happen because of two reasons: either everything wet well (the error parameter will be none) or an exception happened, in which case the error is passed to the tear down function.
    • The app.cli.command() registers a new command with the flask script. When the command executes, flask will automatically create an application context which is bound to the right applcation. Within this function, you can then access flask.g and other things as you might expect. When the script ends, the application context tears down and the database connection is released
    • The open_resource() method of the application object is a convenient helper function that will open a resource that the application provides. This function opens a file from the resource location (the flaskr/flaskr folder) and allows you to read from it. It is used in this example to execute a script on the database connection.
    • The connection object provided by SQLite can give you a cursor object. On that cursor, there is a method to execute a complete script. Finally, you only have to commit the changes. SQLite3 and other transactional databases will not commit unless you explicitly tell it to.

3 SQLALchemy

參考資料

http://blog.csdn.net/buster2014/article/details/50933081

http://www.jb51.net/article/49789.htm

簡單介紹和案例

似乎ORM最難設計的部分是查詢。特別是面向對象的查詢,今天學習SQLAlchemy,發現SQLAlchemy的查詢語法竟如此靈活,驚歎其如此強大的表達能力的同時也對Python也有了更深的認識。下面看一下我寫的一些查詢語句:

# 簡單查詢
# 注意User是一個類對象,user_table是數據庫中的表

print(session.query(User).all())
# —相當於SQL語句—> select * from user_table
print(session.query(User.name,User.fullname.all()))
# —相當於SQL語句—> select user_table.name,user_table.fullname from user_table
print(session.query(User,user.name).all())
# —相當於SQL語句—> select user_table.name from user_table

# 條件查詢
print (session.query(User).filter_by(name=’user1).all())
# —相當於SQL語句—> select * from user_table where name = ‘user1’
print (session.query(User).filter(User.name == “user).all())
# —相當於SQL語句—> select * from user_table where user_table.name = user
print (session.query(User).filter(User.name.like(“user%”)).all())
# —相當於SQL語句—> select * from user_table where user_table.name like user%

# 多條件查詢
print (session.query(User).filter(and_(User.name.like(“user),User.fullname.like(“first%”))).all()
# —相當於SQL語句—>
# select * from user_table where user_table.name like %user and user_table.fullname # like first%
print (session.query(User).filter(or_(User.name.like(“user%),User.password != None)).all()
# —相當於SQL語句—>
# select * from user_table where user_table.name = user% or user_table.password != # none

# sql過濾
print (session(User).filter(“id>:id”).params(id=1).all()
# —相當於SQL語句—> select * from user_table where user_table.id > 1

# 關聯查詢
print (session.query(User,Address).filter(User.id == Address.user_id).all()
# —相當於SQL語句—> 
# select * from user_table,address_table where user_table.id == address.user_id
print (session.query(User).jion(User.address).all()
print (session.query(User).outerjoin(User.address).all())

# 聚合查詢
print (session.query(User.name,func.count(‘*’).label(“user_count)).group_by(User.name).all())
# —相當於SQL語句—>
# select count(user_table.name) as user_count 
# from user_table where ... group by(user_table.name)

print (session.query(User.name,func.sum(User.id).label(“user_id_sum”)).group_by(User.name).all())
# —相當於SQL語句—>
# select user_table.name,sum(user_table.id)  from user_table 
# where group by(user_table.name)

# 子查詢
stmt = session.query(Address.user_id,func.count(‘*’).label(“address_count”).group by(Address.user_id).subquery()
print (session.query(User,stmt.c.address_count).outjion((stmt,User.id == stmt.c.user_id.order_by(User_id).all()

# exits
print (session.query(User).filter(exists().where(Address.user_id == User.id)))
print (session.query(User).filter(User.addresses.any()))

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章