Thứ năm, 16/01/2014 | 00:00 GMT+7

Cách cấu trúc các ứng dụng flask lớn

Có nhiều phương pháp và quy ước để cấu trúc các ứng dụng web Python. Mặc dù một số khung công tác nhất định được vận chuyển với các công cụ (dành cho giàn giáo) để tự động hóa - và dễ dàng - nhiệm vụ (và các vấn đề đau đầu), hầu như tất cả các giải pháp đều dựa vào ứng dụng đóng gói / module hóa khi cơ sở mã được phân phối [hợp lý] trên các file và folder liên quan.


Khung phát triển ứng dụng web tối giản Flask, có bản thiết kế riêng của nó.

Trong bài viết DigitalOcean này, ta sẽ xem cách tạo folder ứng dụng và cấu trúc nó để hoạt động với các thành phần có thể sử dụng lại được tạo bằng bản thiết kế của Flask. Những phần này cho phép (và đơn giản hóa) việc bảo trì và phát triển các thành phần ứng dụng rất nhiều.

Bảng chú giải


1. Flask: Khung phát triển ứng dụng tối giản


2. Lựa chọn của ta trong bài viết này


3. Chuẩn bị hệ thống cho bình


  1. Chuẩn bị hệ điều hành
  2. Cài đặt Python, pip và virtualenv

4. Cấu trúc Thư mục Ứng dụng


  1. Tạo folder ứng dụng
  2. Tạo môi trường ảo
  3. Tạo file ứng dụng
  4. Cài đặt bình

5. Làm việc với Mô-đun và Bản thiết kế (Thành phần)


  1. Kiến thức cơ bản về module
  2. Mẫu module

6. Tạo Ứng dụng (run.py, init .py, v.v.)


  1. Chỉnh sửa run.py bằng nano
  2. Chỉnh sửa config.py bằng nano

7. Tạo Mô-đun / Thành phần


  1. Bước 1: Cấu trúc Mô-đun
  2. Bước 2: Xác định (các) Mô hình Dữ liệu Mô-đun
  3. Bước 3: Xác định Biểu mẫu Mô-đun
  4. Bước 4: Xác định Bộ điều khiển ứng dụng (Chế độ xem)
  5. Bước 5: Cài đặt ứng dụng trong “app / init .py”
  6. Bước 6: Tạo Mẫu
  7. Bước 7: Xem module của bạn đang hoạt động

Flask: Khung phát triển ứng dụng tối giản


Flask là một khuôn khổ tối giản (hoặc vi mô), không áp đặt cách xử lý những việc quan trọng. Thay vào đó, Flask cho phép các nhà phát triển sử dụng các công cụ mà họ mong muốn và quen thuộc. Vì mục đích này, nó đi kèm với index tiện ích mở rộng của riêng nó và một lượng lớn công cụ đã tồn tại để xử lý khá nhiều thứ từ đăng nhập đến ghi log .

Nó không phải là một khuôn khổ “thông thường” hoàn toàn và dựa một phần vào các file cấu hình, điều này thực sự làm cho nhiều thứ dễ dàng hơn khi bắt đầu và giữ mọi thứ trong tầm kiểm soát.

Lựa chọn của ta trong bài viết này


Như ta đã trình bày ở phần trước, cách hoạt động của Flask liên quan đến việc sử dụng các công cụ mà bạn thấy phù hợp nhất. Trong bài viết của ta , ta sẽ sử dụng - có lẽ - là lựa chọn phổ biến nhất (và hợp lý) về phần mở rộng và thư viện (tức là lớp extract database ). Những lựa chọn này sẽ bao gồm:

  • SQLAlchemy (thông qua Flask-SQLAlchemy)

  • WTForms (thông qua Flask-WTF)

Flask-SQLAlchemy


Thêm hỗ trợ SQLAlchemy vào Flask. Nhanh chóng và dễ dàng.

Đây là một phần mở rộng đã được phê duyệt.

Author: Armin Ronacher PyPI Page: Flask-SQLAlchemy Documentation: Read docs @ packages.python.org On Github: [mitsuhiko/flask-sqlalchemy](https://github.com/mitsuhiko/flask-sqlalchemy) 

Flask-WTF


Flask-WTF cung cấp tích hợp đơn giản với WTForms. Tích hợp này bao gồm xử lý CSRF tùy chọn để bảo mật cao hơn.

Đây là một phần mở rộng đã được phê duyệt.

Author: Anthony Ford (created by Dan Jacob) PyPI Page: Flask-WTF Documentation: Read docs @ packages.python.org On Github: [ajford/flask-wtf](https://github.com/mitsuhiko/flask-wtf) 

Chuẩn bị hệ thống cho bình


Trước khi bắt đầu cấu trúc một ứng dụng Flask lớn, hãy chuẩn bị hệ thống và download (và cài đặt) bản phân phối Flask.

Lưu ý: Ta sẽ làm việc trên một server mới được khởi tạo chạy version mới nhất của hệ điều hành có sẵn (tức là Ubuntu 13). Bạn cũng nên thử nghiệm mọi thứ trên một hệ thống mới - đặc biệt nếu bạn đang tích cực phục vụ khách hàng.

Chuẩn bị hệ điều hành


Để có một server ổn định, ta phải có tất cả các công cụ và thư viện liên quan được cập nhật và bảo trì tốt.

Để đảm bảo ta có các version ứng dụng mặc định mới nhất hiện có, hãy bắt đầu với các bản cập nhật.

Chạy phần sau cho Hệ thống dựa trên Debian (tức là Ubuntu, Debian):

aptitude    update aptitude -y upgrade 

Để có được các công cụ phát triển cần thiết, hãy cài đặt "build-essential" bằng lệnh sau:

aptitude install -y build-essential python-dev python2.7-dev 

Cài đặt Python, pip và virtualenv


Trên Ubuntu và Debian, version trình thông dịch Python gần đây - mà bạn có thể sử dụng - được cung cấp theo mặc định. Nó khiến ta chỉ có một số gói bổ sung hạn chế để cài đặt:

  • python-dev (công cụ phát triển)

  • pip (để quản lý các gói)

  • virtualenv (để tạo riêng biệt, ảo

Lưu ý: Hướng dẫn đưa ra ở đây được giữ ngắn gọn. Để tìm hiểu thêm, hãy xem bài viết hướng dẫn của ta về pip và virtualenv: Các công cụ Python phổ biến: Sử dụng virtualenv, Cài đặt bằng Pip và Quản lý các gói .

pip


pip là một trình quản lý gói sẽ giúp ta cài đặt các gói ứng dụng mà ta cần.

Chạy các lệnh sau để cài đặt pip:

curl https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py | python - curl https://raw.github.com/pypa/pip/master/contrib/get-pip.py | python - export PATH="/usr/local/bin:$PATH" 

virtualenv


Tốt nhất là chứa một ứng dụng Python trong môi trường riêng của nó cùng với tất cả các phụ thuộc của nó. Một môi trường có thể được mô tả tốt nhất (theo thuật ngữ đơn giản) như một vị trí biệt lập (một folder ), nơi mọi thứ cư trú. Với mục đích này, một công cụ gọi là virtualenv được sử dụng.

Chạy phần sau để cài đặt virtualenv bằng pip:

sudo pip install virtualenv 

Cấu trúc Thư mục Ứng dụng


Ta sẽ sử dụng tên mẫu của LargeApp làm folder ứng dụng của ta . Bên trong, ta sẽ có một môi trường ảo (tức là env) cùng với gói ứng dụng (tức là ứng dụng) và một số file khác như “run.py” để chạy server thử nghiệm (phát triển) và “config.py” để giữ Cấu hình bình.

Cấu trúc - được đưa ra như một ví dụ bên dưới - rất có thể mở rộng và nó được xây dựng để tận dụng tất cả các công cụ hữu ích mà Flask và các thư viện khác cung cấp. Đừng sợ khi bạn nhìn thấy nó, vì ta giải thích mọi thứ từng bước bằng cách xây dựng tất cả.

Cấu trúc ví dụ mục tiêu:

~/LargeApp     |-- run.py     |-- config.py     |__ /env             # Virtual Environment     |__ /app             # Our Application Module          |-- __init__.py          |-- /module_one              |-- __init__.py              |-- controllers.py              |-- models.py                          |__ /templates              |__ /module_one                  |-- hello.html          |__ /static          |__ ..          |__ .     |__ ..     |__ . 

Tạo folder ứng dụng


Hãy bắt đầu với việc tạo các folder chính mà ta cần.

Chạy các lệnh sau liên tiếp để thực hiện tác vụ:

mkdir ~/LargeApp mkdir ~/LargeApp/app mkdir ~/LargeApp/app/templates mkdir ~/LargeApp/app/static     

Cấu trúc hiện tại của ta :

~/LargeApp     |__ /app             # Our Application Module          |__ /templates          |__ /static 

Tạo môi trường ảo


Sử dụng môi trường ảo mang lại rất nhiều lợi ích. Bạn rất nên sử dụng môi trường ảo mới cho từng ứng dụng của bạn . Giữ folder virtualenv bên trong ứng dụng của bạn là một cách tốt để giữ mọi thứ ngăn nắp và gọn gàng.

Chạy phần sau để tạo một môi trường ảo mới có cài đặt pip .

cd         ~/LargeApp virtualenv env 

Tạo file ứng dụng


Trong bước này, ta sẽ hình thành các file ứng dụng cơ bản trước khi chuyển sang làm việc với các module và bản thiết kế.

Chạy các bước sau để tạo các file ứng dụng cơ bản:

touch ~/LargeApp/run.py touch ~/LargeApp/config.py touch ~/LargeApp/app/__init__.py 

Cấu trúc hiện tại của ta :

~/LargeApp     |-- run.py     |-- config.py     |__ /env             # Virtual Environment     |__ /app             # Our Application Module          |-- __init__.py          |__ /templates          |__ /static 

Cài đặt bình và phụ thuộc ứng dụng


Khi ta đã có mọi thứ, để bắt đầu phát triển Flask, hãy download và cài đặt nó bằng pip.

Chạy phần sau để cài đặt Flask bên trong môi trường ảo env.

cd ~/LargeApp env/bin/pip install flask env/bin/pip install flask-sqlalchemy env/bin/pip install flask-wtf 

Lưu ý: Ở đây ta đang tải và cài đặt Flask mà không cần kích hoạt môi trường ảo. Tuy nhiên, do ta đang sử dụng pip từ chính môi trường, nó sẽ đạt được nhiệm vụ tương tự. Nếu bạn đang làm việc với một môi trường được kích hoạt, bạn chỉ có thể sử dụng pip để thay thế.

Và đó là nó! Bây giờ ta đã sẵn sàng xây dựng một ứng dụng Flask lớn hơn được module hóa bằng cách sử dụng các bản thiết kế.

Làm việc với Mô-đun và Bản thiết kế (Thành phần)


Kiến thức cơ bản về module


Đến đây, ta đã cài đặt cả cấu trúc ứng dụng và các phụ thuộc của nó đã được download và sẵn sàng.

Mục tiêu của ta là module hóa (tức là tạo các thành phần có thể sử dụng lại bằng bản thiết kế của Flask) tất cả các module liên quan có thể được group lại một cách hợp lý.

Một ví dụ cho điều này có thể là một hệ thống xác thực. Việc có tất cả các khung nhìn, bộ điều khiển, mô hình và trình trợ giúp ở một nơi, được cài đặt theo cách cho phép khả năng tái sử dụng khiến loại cấu trúc này trở thành một cách tốt để duy trì ứng dụng đồng thời tăng năng suất.

Cấu trúc module (thành phần) mẫu đích (bên trong /app ):

# Our module example here is called *mod_auth* # You can name them as you like as long as conventions are followed  /mod_auth     |-- __init__.py     |-- controllers.py     |-- models.py     |-- ..     |-- . 

Mẫu module


Để hỗ trợ module hóa thành-tối đa, ta sẽ cấu trúc folder “mẫu” để tuân theo quy ước trên và chứa một folder mới - có tên giống hoặc tương tự, có liên quan với module - để chứa các file mẫu của nó.

Nhắm đến cấu trúc folder mẫu ví dụ (bên trong LargeApp ):

/templates     |-- 404.html     |__ /auth          |-- signin.html          |-- signup.html          |-- forgot.html          |-- ..          |-- . 

Tạo ứng dụng


Trong phần này, ta sẽ tiếp tục các bước trước đó và bắt đầu với mã hóa thực tế ứng dụng của bạn trước khi chuyển sang tạo thành phần được module hóa đầu tiên của ta (sử dụng bản thiết kế): mod_auth để xử lý tất cả các thủ tục liên quan đến xác thực (tức là đăng nhập, đăng ký, v.v. ).

Chỉnh sửa “run.py” bằng nano


nano ~/LargeApp/run.py 

Đặt nội dung:

# Run a test server. from app import app app.run(host='0.0.0.0', port=8080, debug=True) 

Lưu và thoát bằng CTRL + X và xác nhận bằng Y.

Chỉnh sửa “config.py” bằng nano


nano ~/LargeApp/config.py 

Đặt nội dung:

# Statement for enabling the development environment DEBUG = True  # Define the application directory import os BASE_DIR = os.path.abspath(os.path.dirname(__file__))    # Define the database - we are working with # SQLite for this example SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(BASE_DIR, 'app.db') DATABASE_CONNECT_OPTIONS = {}  # Application threads. A common general assumption is # using 2 per available processor cores - to handle # incoming requests using one and performing background # operations using the other. THREADS_PER_PAGE = 2  # Enable protection agains *Cross-site Request Forgery (CSRF)* CSRF_ENABLED     = True  # Use a secure, unique and absolutely secret key for # signing the data.  CSRF_SESSION_KEY = "secret"  # Secret key for signing cookies SECRET_KEY = "secret" 

Lưu và thoát bằng CTRL + X và xác nhận bằng Y.

Tạo Mô-đun / Thành phần


Phần này là bước chính đầu tiên xác định cốt lõi của bài viết này. Ở đây, ta sẽ xem cách sử dụng các bản thiết kế của Flask để tạo một module (tức là một thành phần).

Điều tuyệt vời về điều này là tính di động được cung cấp và khả năng tái sử dụng của mã của bạn, kết hợp với việc dễ dàng bảo trì - điều mà bạn sẽ rất biết ơn trong tương lai vì thường thì sẽ khá vất vả để quay lại và hiểu mọi thứ như chúng đã bỏ đi.

Bước 1: Cấu trúc Mô-đun


Như ta đã bắt đầu làm, hãy để ta tạo các folder và file của module đầu tiên ( mod_auth ) để bắt đầu làm việc với chúng.

# Create the module directory inside the *app* module mkdir ~/LargeApp/app/mod_auth  # Create where module's templates will reside mkdir ~/LargeApp/app/templates/auth  # Create __init__.py to set the directory as a Python module touch ~/LargeApp/app/mod_auth/__init__.py  # Create module's controllers and models etc. touch ~/LargeApp/app/mod_auth/controllers.py touch ~/LargeApp/app/mod_auth/models.py touch ~/LargeApp/app/mod_auth/forms.py  # Create module's templates touch ~/LargeApp/app/templates/auth/signin.html  # Create a HTTP 404 Error page touch ~/LargeApp/app/templates/404.html 

Sau các thao tác này, đây là cách cấu trúc folder sẽ trông như thế nào:

~/LargeApp     |-- run.py     |-- config.py     |__ /env             # Virtual Environment     |__ /app             # Our Application Module          |-- __init__.py          |-- /mod_auth   # Our first module, mod_auth              |-- __init__.py              |-- controllers.py              |-- models.py              |-- forms.py          |__ /templates              |-- 404.html              |__ /auth                  |-- signin.html          |__ /static 

Bước 2: Xác định (các) Mô hình Dữ liệu Mô-đun


nano ~/LargeApp/app/mod_auth/models.py 

Đặt phần dưới đây tự giải thích - mẫu mực - nội dung:

# Import the database object (db) from the main application module # We will define this inside /app/__init__.py in the next sections. from app import db  # Define a base model for other database tables to inherit class Base(db.Model):      __abstract__  = True      id            = db.Column(db.Integer, primary_key=True)     date_created  = db.Column(db.DateTime,  default=db.func.current_timestamp())     date_modified = db.Column(db.DateTime,  default=db.func.current_timestamp(),                                            onupdate=db.func.current_timestamp())  # Define a User model class User(Base):      __tablename__ = 'auth_user'      # User Name     name    = db.Column(db.String(128),  nullable=False)      # Identification Data: email & password     email    = db.Column(db.String(128),  nullable=False,                                             unique=True)     password = db.Column(db.String(192),  nullable=False)      # Authorisation Data: role & status     role     = db.Column(db.SmallInteger, nullable=False)     status   = db.Column(db.SmallInteger, nullable=False)      # New instance instantiation procedure     def __init__(self, name, email, password):          self.name     = name         self.email    = email         self.password = password      def __repr__(self):         return '<User %r>' % (self.name)                         

Lưu và thoát bằng CTRL + X và xác nhận bằng Y.

Bước 3: Xác định Biểu mẫu Mô-đun


nano ~/LargeApp/app/mod_auth/forms.py 

Đặt phần dưới đây tự giải thích - mẫu mực - nội dung:

# Import Form and RecaptchaField (optional) from flask.ext.wtf import Form # , RecaptchaField  # Import Form elements such as TextField and BooleanField (optional) from wtforms import TextField, PasswordField # BooleanField  # Import Form validators from wtforms.validators import Required, Email, EqualTo   # Define the login form (WTForms)  class LoginForm(Form):     email    = TextField('Email Address', [Email(),                 Required(message='Forgot your email address?')])     password = PasswordField('Password', [                 Required(message='Must provide a password. ;-)')]) 

Lưu và thoát bằng CTRL + X và xác nhận bằng Y.

Bước 4: Xác định Bộ điều khiển ứng dụng (Chế độ xem)


nano ~/LargeApp/app/mod_auth/controllers.py 

Đặt phần dưới đây tự giải thích - mẫu mực - nội dung:

# Import flask dependencies from flask import Blueprint, request, render_template, \                   flash, g, session, redirect, url_for  # Import password / encryption helper tools from werkzeug import check_password_hash, generate_password_hash  # Import the database object from the main app module from app import db  # Import module forms from app.mod_auth.forms import LoginForm  # Import module models (i.e. User) from app.mod_auth.models import User  # Define the blueprint: 'auth', set its url prefix: app.url/auth mod_auth = Blueprint('auth', __name__, url_prefix='/auth')  # Set the route and accepted methods @mod_auth.route('/signin/', methods=['GET', 'POST']) def signin():      # If sign in form is submitted     form = LoginForm(request.form)      # Verify the sign in form     if form.validate_on_submit():          user = User.query.filter_by(email=form.email.data).first()          if user and check_password_hash(user.password, form.password.data):              session['user_id'] = user.id              flash('Welcome %s' % user.name)              return redirect(url_for('auth.home'))          flash('Wrong email or password', 'error-message')      return render_template("auth/signin.html", form=form) 

Lưu và thoát bằng CTRL+X và xác nhận bằng Y

Bước 5: Cài đặt ứng dụng trong “app / init .py”


nano ~/LargeApp/app/__init__.py 

Đặt nội dung:

# Import flask and template operators from flask import Flask, render_template  # Import SQLAlchemy from flask.ext.sqlalchemy import SQLAlchemy  # Define the WSGI application object app = Flask(__name__)  # Configurations app.config.from_object('config')  # Define the database object which is imported # by modules and controllers db = SQLAlchemy(app)  # Sample HTTP error handling @app.errorhandler(404) def not_found(error):     return render_template('404.html'), 404  # Import a module / component using its blueprint handler variable (mod_auth) from app.mod_auth.controllers import mod_auth as auth_module  # Register blueprint(s) app.register_blueprint(auth_module) # app.register_blueprint(xyz_module) # ..  # Build the database: # This will create the database file using SQLAlchemy db.create_all() 

Lưu và thoát bằng CTRL + X và xác nhận bằng Y.

Bước 6: Tạo Mẫu


nano ~/LargeApp/app/templates/auth/signin.html 

Đặt nội dung:

{% macro render_field(field, placeholder=None) %} {% if field.errors %} <div> {% elif field.flags.error %} <div> {% else %} <div> {% endif %}     {% set css_class = 'form-control ' + kwargs.pop('class', '') %}     {{ field(class=css_class, placeholder=placeholder, **kwargs) }} </div> {% endmacro %}  <div>   <div>     <legend>Sign in</legend>     {% with errors = get_flashed_messages(category_filter=["error"]) %}     {% if errors %}     <div>     {% for error in errors %}     {{ error }}<br>     {% endfor %}     </div>     {% endif %}     {% endwith %}      {% if form.errors %}     <div>     {% for field, error in form.errors.items() %}     {% for e in error %}     {{ e }}<br>     {% endfor %}     {% endfor %}     </div>     {% endif %}     <form method="POST" action="." accept-charset="UTF-8" role="form">       {{ form.csrf_token }}       {{ render_field(form.email, placeholder="Your Email Address",                                   autofocus="") }}       {{ render_field(form.password, placeholder="Password") }}       <div>       <label>         <input type="checkbox" name="remember" value="1"> Remember Me       </label>       <a role="button" href="">Forgot your password?</a><span class="clearfix"></span>       </div>       <button type="submit" name="submit">Sign in</button>     </form>     </div> </div> 

Lưu và thoát bằng CTRL + X và xác nhận bằng Y.

Lưu ý: Tệp mẫu này là một ví dụ rất đơn giản và chưa hoàn chỉnh vừa được tạo cho mục đích demo . Ta rất khuyến khích bạn đọc tài liệu Jinja2 và sử dụng các file cơ sở để xây dựng các mẫu trang web .

Bước 7: Xem module của bạn đang hoạt động


Sau khi tạo module đầu tiên của ta , đây là lúc để xem mọi thứ hoạt động.

Chạy server phát triển bằng run.py :

cd ~/LargeApp env/bin/python run.py 

Điều này sẽ bắt đầu một server phát triển (tức là thử nghiệm) được lưu trữ tại cổng 8080 .

Truy cập module bằng cách truy cập URL:

http://[your server's IP]/auth/signin 

Mặc dù bạn sẽ không thể đăng nhập, nhưng bạn có thể thấy nó hoạt động bằng lệnh một số dữ liệu mẫu hoặc bằng cách kiểm tra trình xác thực của nó.

<div class = “author”> Gửi bởi: <a
href = “https://twitter.com/ostezer”> Hệ điều hành Tezer </a> </div>


Tags:

Các tin liên quan