Skip to main content

niceDjango Extension Framework

Project description

niceDjango Extension Framework

提供 Python/Django 擴展之開發框架。

概述

擴展 (Extension) 用來提供給呼叫端,無須知道具體實作方式,便可取得實作對象 (Target) 之機制。

每一個擴展需定義:

  • extension_type: 擴展的類型。使用 [A-z_-.][A-z0-9_-.] 組成之字串。
  • extension_id: 擴展的識別碼。使用 [A-z_-.][A-z0-9_-.] 組成之字串。空值或省略時,將以擴展的識別子 ( 類別名稱,或函數名稱) 做為識別碼。
  • label: 擴展的標籤,給人類看的名稱。空值或省略時,將以擴展的識別子 (類別名稱,或函數名稱) 做為標籤。
  • description:給人類閱讀的描述。

擴展的完整識別子 (Identifier) 為 extension_type:extension_id

功能

  • 簡化擴展之開發。
  • 可從所有 EGG 中載入指定的擴展。
  • 提供給 Django Model 使用的 Field 類別,以保存擴展資訊到資料庫。
  • 提供給 Django Form 使用的 Field 類別,讓用戶可從表單選取或設定擴展。
  • 提供給 Django REST Framework 使用的 Field 類別,讓 API Client 可以選取或設定擴展。

安裝

$ pip install nsd-extension-framework

使用

宣告擴展 (Declaration extension)

首先,你需要先宣告你的擴展。擴展可以是一個類別 (Class),也可以是一個函數 (Function)。

每個擴展都需使用 @extension 裝飾器宣告其為擴展:

from django.utils.translation import gettext as _

from nsd_extension_framework import extension


@extension(
    extension_type="foo",
    extension_id="boo_class",
    label=_("Boo Class Extension")
)
class BooExtension:
    def test(self):
        print("Boo Class Extension - Test")


@extension(
    extension_type="foo",
    extension_id="boo_function",
    label=_("Boo Function Extension")
)
def boo():
    print("Boo Function Extension - Test")

註冊你的擴展 (Register your extensions)

宣告擴展後,可在使用之前註冊你的擴展。註冊的方法有兩種:

  • 使用代碼
  • 使用 EGG EntryPoint

使用代碼

例如,在 Django 中,你可以透過 AppConfig.ready() 來註冊之:

from django.apps import AppConfig as _AppConfig


class AppConfig(_AppConfig):
    def ready(self):
        from myapp.extensions import BooExtension, boo  # NOQA
        from nsd_extension_framework import factory
        factory.register(BooExtension).register(boo)

使用 EGG EntryPoint

請在你的 Python EGG 套件中,定義一個 EntryPoint。

例如 pyproject.toml 中:

[project.entry-points."AppExtensions"]
"foo:boo_class" = "myapp.extensions:BooExtension"
"foo:boo_function" = "myapp.extensions:boo"

或是 setup.py 中:

from setuptools import setup  # NOQA

setup(
    # ...
    entry_points={
        "AppExtensions": {
            "foo:boo_class": "myapp.extensions:BooExtension",
            "foo:boo_function": "myapp.extensions:boo",
        }
    },
)

然後在使用之前,透過 nsd_extension_framework.factory.load() 從所有的 EGG 套件中載入所有擴展:

from django.apps import AppConfig as _AppConfig


class AppConfig(_AppConfig):
    def ready(self):
        from nsd_extension_framework import factory
        factory.load(entry_point_group_name="AppExtensions")

取得擴展 (Get extension)

註冊後,可以在程序運行的任何時候,透過 factory.get_extension() 來取得擴展:

from nsd_extension_framework import factory

boo_class = factory.get_extension("foo:boo_class")
extension = boo_class()
extension.test()
# Boo Class Extension - Test

boo_function = factory.get_extension("foo:boo_function")
boo_function()
# Boo Function Extension - Test

進階 (Advanced)

Django 模型欄位 (Django Model Field)

本套件中提供 nsd_extension_framework.db.ExtensionField,讓你可以將擴展資訊保存到資料庫中。

使用範例:

from django.db import models

from nsd_extension_framework.db import ExtensionField
from myapp.extensions import BooExtension   # NOQA


class ExtensionModel(models.Model):
    extension = ExtensionField(
        required=False,
        db_index=True
    )


ext = ExtensionModel(extension=BooExtension)
# 回傳 BooExtension 實例
impl = ext.extension()
# 呼叫 BooExtension.test()
impl.test()

Django 表單欄位 (Django Form Field)

from django import forms

from nsd_extension_framework import Extension
from nsd_extension_framework.forms import ExtensionField


class BooForm(forms.Form):
    extension = ExtensionField(
        required=False,
    )


def boo_form_post(request):
    form = BooForm(request.POST)
    if form.is_valid():
        # 回傳 BooExtension 實例
        extension = form.cleaned_data["extension"]
        if extension:
            # 取得 Extension 的 FullID
            opts = Extension.get_extension_options(extension)
            if opts:
                print(opts.full_id)

目前也支援 Django ModelForm:

from django import forms
from myapp.models import ExtensionModel  # NOQA


# 自定義的 ModelForm
class BooModelForm(forms.ModelForm):
    class Meta:
        model = ExtensionModel
        fields = '__all__'


# 使用 modelform_factory() 建立 ModelForm

ModelForm = forms.modelform_factory(ExtensionModel, fields='__all__')

Django REST Framework 欄位 (Django REST Framework Field)

from rest_framework import serializers

from nsd_extension_framework.drf import ExtensionField


class BooSerializer(serializers.Serializer):
    extension = ExtensionField(
        required=False,
    )

也支援 ModelSerializer:

from rest_framework import serializers
from myapp.models import ExtensionModel  # NOQA


class ExtensionModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = ExtensionModel
        field = '__all__'

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nsd_extension_framework-0.1.0.tar.gz (13.2 kB view details)

Uploaded Source

File details

Details for the file nsd_extension_framework-0.1.0.tar.gz.

File metadata

  • Download URL: nsd_extension_framework-0.1.0.tar.gz
  • Upload date:
  • Size: 13.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for nsd_extension_framework-0.1.0.tar.gz
Algorithm Hash digest
SHA256 1a238532782ecf6f072a109642936395e0ffc4e170b52bb8711b113020cba615
MD5 0349b37e97aa46dd33e96e562c4c5231
BLAKE2b-256 482fb36d9e90693f9b6811bae316e18e803340a050180a0e69f7cf3248e55c48

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page