在 Flask 應用程式中,我們可以利用 Flask-Admin 快速建立管理後台,並整合 CKEditor 提供 WYSIWYG 編輯功能,讓使用者更方便地編輯富文字內容。同時,為了提升管理介面的安全性,我們可以加入根據角色的許可權控管,限制不同角色的使用者操作許可權。最後,為了讓應用程式更具國際化,我們可以使用 Flask-Babel 套件輕鬆地實作多語言支援,讓不同語系的使用者都能夠順暢地使用應用程式。

在Flask應用程式中建立具有WYSIWYG編輯器的管理介面

本章節將介紹如何在Flask應用程式中建立一個具有WYSIWYG(所見即所得)編輯器的管理介面。我們將使用Flask-Admin擴充套件來建立一個功能豐富的管理後台,並整合CKEditor作為WYSIWYG編輯器。

為管理介面新增WYSIWYG編輯器

要在Flask-Admin的管理介面中使用WYSIWYG編輯器,我們需要進行以下步驟:

  1. 修改模型:首先,在auth/models.py中為User模型新增一個名為notes的欄位,用於儲存使用WYSIWYG編輯器建立的內容。

class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(100)) pwdhash = db.Column(db.String()) admin = db.Column(db.Boolean()) notes = db.Column(db.UnicodeText)

def __init__(self, username, password, admin=False, notes=''):
    self.username = username
    self.pwdhash = generate_password_hash(password)
    self.admin = admin
    self.notes = notes
#### 內容解密:
- `notes`欄位使用`db.UnicodeText`型別,可以儲存大量的文字內容。
- 在`__init__`方法中,`notes`引數預設為空字串,允許在建立使用者時可選地提供額外的備註資訊。

2. **建立自定義WTForm小工具和欄位**:接著,在`auth/models.py`中建立一個自定義的WTForm小工具和欄位,用於渲染CKEditor。
```python
from wtforms import widgets, TextAreaField

class CKTextAreaWidget(widgets.TextArea):
 def __call__(self, field, **kwargs):
     kwargs.setdefault('class_', 'ckeditor')
     return super(CKTextAreaWidget, self).__call__(field, **kwargs)

class CKTextAreaField(TextAreaField):
 widget = CKTextAreaWidget()

內容解密:

  • CKTextAreaWidget類別繼承自widgets.TextArea,並在渲染時為textarea元素新增ckeditor類別。
  • CKTextAreaField類別繼承自TextAreaField,並使用CKTextAreaWidget作為其小工具。
  1. 修改UserAdminView類別:然後,在auth/views.py中修改UserAdminView類別,以使用自定義的CKEditor欄位。

from auth.models import CKTextAreaField

class UserAdminView(ModelView): form_overrides = dict(notes=CKTextAreaField) create_template = ’edit.html' edit_template = ’edit.html'

#### 內容解密:
- `form_overrides`屬性用於覆寫預設的表單欄位,這裡將`notes`欄位替換為`CKTextAreaField`。
- 指定了建立和編輯範本為`edit.html`,以便載入CKEditor的JavaScript檔案。

4. **編寫範本**:最後,在`templates/edit.html`中擴充套件預設的編輯範本,並載入CKEditor的JavaScript檔案。
```html
{% extends 'admin/model/edit.html' %}

{% block tail %}
 {{ super() }}
 <script src="https://cdn.ckeditor.com/4.20.1/standard/ckeditor.js"></script>
{% endblock %}

內容解密:

  • 擴充套件了Flask-Admin預設的edit.html範本,以保持原有的功能。
  • 在頁尾區塊載入了CKEditor的JavaScript檔案,使其生效。

結果

經過上述步驟後,管理介面中的使用者建立和編輯表單將會使用CKEditor作為備註欄位的WYSIWYG編輯器。使用者可以利用CKEditor提供的豐富功能來格式化文字,從而使得備註資訊更具可讀性和視覺吸引力。

建立使用者角色

為了進一步增強管理介面的功能,我們可以實作根據角色的存取控制(RBAC)。這涉及到為使用者模型新增角色欄位,並根據角色限制使用者對特定檢視的存取。

  1. 新增角色欄位:首先,在使用者模型中新增一個名為roles的欄位。

class User(db.Model): # … roles = db.Column(db.String(4))

def __init__(self, username, password, admin=False, notes='', roles='R'):
    # ...
    self.roles = self.admin and roles or ''
#### 內容解密:
- `roles`欄位用於儲存使用者的角色資訊,例如CRUD(建立、讀取、更新、刪除)許可權。

2. **修改UserAdminView類別**:接著,更新`UserAdminView`類別,以包含角色欄位並處理相關邏輯。
```python
from flask_admin.actions import ActionsMixin

class UserAdminView(ModelView, ActionsMixin):
 form_edit_rules = ('username', 'admin', 'roles', 'notes', rules.Header('Reset Password'), 'new_password', 'confirm')
 form_create_rules = ('username', 'admin', 'roles', 'notes', 'password')

內容解密:

  • 在建立和編輯表單中增加了roles欄位,以便管理員可以為使用者分配不同的角色。

透過實作上述功能,我們可以在Flask應用程式中建立一個具有WYSIWYG編輯器和根據角色的存取控制的管理介面,從而提高應用的可管理性和安全性。

在Flask應用程式中實作管理介面與多語言支援

管理介面與許可權控制

在開發Flask應用程式時,管理介面是至關重要的部分。本文將介紹如何實作一個具備許可權控制的管理介面。首先,我們需要定義不同角色的使用者許可權,例如建立、更新和刪除記錄。

許可權控制方法實作

以下程式碼展示瞭如何實作許可權控制方法:

def create_model(self, form):
    if 'C' not in current_user.roles:
        flash('您無權建立使用者。', 'warning')
        return
    model = self.model(
        form.username.data, form.password.data,
        form.admin.data, form.notes.data
    )
    form.populate_obj(model)
    self.session.add(model)
    self._on_model_change(form, model, True)
    self.session.commit()

def update_model(self, form, model):
    if 'U' not in current_user.roles:
        flash('您無權編輯使用者。', 'warning')
        return
    form.populate_obj(model)
    if form.new_password.data:
        if form.new_password.data != form.confirm.data:
            flash('密碼必須比對')
            return
        model.pwdhash = generate_password_hash(form.new_password.data)
    self.session.add(model)
    self._on_model_change(form, model, False)
    self.session.commit()

def delete_model(self, model):
    if 'D' not in current_user.roles:
        flash('您無權刪除使用者。', 'warning')
        return
    super(UserAdminView, self).delete_model(model)

def is_action_allowed(self, name):
    if name == 'delete' and 'D' not in current_user.roles:
        flash('您無權刪除使用者。', 'warning')
        return False
    return True

內容解密:

  1. create_model 方法:檢查目前使用者是否具有 ‘C’ 許可權,若無則顯示警告訊息並傳回。否則,建立新的模型例項並提交至資料函式庫。
  2. update_model 方法:檢查目前使用者是否具有 ‘U’ 許可權,若無則顯示警告訊息並傳回。否則,更新模型例項並提交至資料函式庫。
  3. delete_model 方法:檢查目前使用者是否具有 ‘D’ 許可權,若無則顯示警告訊息並傳回。否則,刪除指定的模型例項。
  4. is_action_allowed 方法:檢查目前使用者是否具有執行特定動作的許可權,例如刪除操作。

多語言支援

為了使Flask應用程式支援多語言,我們需要使用Flask-Babel擴充功能。以下步驟將介紹如何新增法語作為第二語言。

安裝Flask-Babel

首先,我們需要安裝Flask-Babel:

$ pip install Flask-Babel

設定多語言支援

接下來,在 my_app/__init__.py 中建立 Babel 例項並設定允許的語言:

from flask import request
from flask_babel import Babel

ALLOWED_LANGUAGES = {
    'en': 'English',
    'fr': 'French',
}

babel = Babel(app)

def get_locale():
    return request.accept_languages.best_match(ALLOWED_LANGUAGES.keys())

babel.init_app(app, locale_selector=get_locale)

內容解密:

  1. 允許的語言:定義了一個字典 ALLOWED_LANGUAGES,其中包含允許的語言程式碼及其對應的語言名稱。
  2. 取得目前語言get_locale 方法根據請求中的 accept_languages 標頭,選擇最合適的語言。
  3. 初始化 Babel:使用 babel.init_app 方法初始化 Babel 例項,並指定 get_locale 方法作為語言選擇器。

透過以上步驟,我們成功地在Flask應用程式中實作了管理介面與多語言支援。這使得我們的應用程式能夠根據使用者的需求,提供更友善的介面和體驗。

國際化與本地化實作

在開發多語言支援的網頁應用程式時,國際化(Internationalization, i18n)與本地化(Localization, L10n)是至關重要的環節。本篇將探討如何利用 Babel 工具實作 Flask 應用程式的多語言支援。

步驟一:組態 Babel

首先,我們需要在專案中建立一個名為 babel.cfg 的檔案,用於組態 Babel 的行為。此檔案的內容如下:

[python: catalog/**.py]
[jinja2: templates/**.html]

這裡定義了 Babel 將要搜尋的檔案模式,用於提取需要翻譯的文字。

步驟二:標記翻譯文字

接下來,我們需要在範本檔案中使用 Babel 提供的 gettext 函式來標記需要翻譯的文字。例如,在 home.html 中:

{% block container %}
<h1>{{ _('歡迎來到產品目錄首頁') }}</h1>
<a href="{{ url_for('catalog.products') }}" id="catalog_link">
    {{ _('點選這裡檢視產品目錄') }}
</a>
{% endblock %}

步驟三:提取翻譯文字

執行以下命令來提取標記的翻譯文字:

$ pybabel extract -F my_app/babel.cfg -o my_app/messages.pot my_app/

此命令將遍歷指定目錄下的檔案,提取出標記為可翻譯的文字,並將其儲存在 my_app/messages.pot 檔案中。

內容解密:

  • -F my_app/babel.cfg 指定了 Babel 的組態檔案。
  • -o my_app/messages.pot 指定了輸出檔案的路徑和名稱。
  • my_app/ 是需要提取翻譯文字的目錄。

步驟四:初始化翻譯檔案

執行以下命令來為指定的語言建立翻譯檔案:

$ pybabel init -i my_app/messages.pot -d my_app/translations -l fr

這將在 my_app/translations 目錄下建立一個名為 fr 的資料夾,並在其中生成 LC_MESSAGES/messages.po 檔案。

內容解密:

  • -i my_app/messages.pot 指定了輸入的 .pot 檔案。
  • -d my_app/translations 指定了輸出翻譯檔案的目錄。
  • -l fr 指定了語言程式碼,這裡是法語。

步驟五:編輯翻譯檔案

使用 Poedit 或其他工具編輯 messages.po 檔案,新增翻譯文字。例如:

#: my_app/catalog/models.py:75
msgid "Not a valid choice"
msgstr "Pas un choix valable"

步驟六:編譯翻譯檔案

完成翻譯後,執行以下命令來編譯 .po 檔案:

$ pybabel compile -d my_app/translations

這將生成一個 .mo 檔案,用於實際的翻譯顯示。

內容解密:

  • 編譯後的 .mo 檔案將被用於顯示翻譯後的文字。

切換語言顯示

透過設定瀏覽器的語言偏好或在應用程式中傳回指定的語言程式碼,可以實作不同語言的顯示切換。

更新翻譯

若需要更新翻譯,可以執行以下命令:

$ pybabel update -i my_app/messages.pot -d my_app/translations

然後重新編譯。

內容解密:

  • 更新命令會根據最新的 .pot 檔案更新現有的翻譯檔案。