可扩展字段,使django应用程序能够将其数据存储在您的模型上。

django-appdata的Python项目详细描述


可扩展字段和相关工具,使django应用程序能够扩展 可重复使用的应用程序。

动机

在使用可重用的django应用程序时,我们经常发现需要添加 应用程序提供的模型或窗体之外的内容。一些应用试图解决 通过提供灵活的模型定义和可插入的形式(参见 django.contrib.comments以这种方法为例)但即使如此 导致一些重复的努力。

django-appdataapp尝试通过AppDataFieldMultiFormAppDataModelAdmin, 提供一个标准化的方法来扩展现有的应用程序。

支持的版本

Python:2.7,3.4,3.5,3.6 django:1.8、1.9、1.10、1.11、2.0、2.1

升级到0.2

如果要从0.1.x版本升级,请注意0.2中的以下不兼容更改

  • 放弃了django<;1.8和python 2.6/3.3的兼容性
  • 已放弃对ModelAdmin.declared_fieldsets属性的支持,请使用ModelAdmin.get_fieldsets方法,如文档所示 低于

扩展模型

当您有一个可扩展的django应用程序时,使用AppDataField

from django.db import models
from app_data import AppDataField

class BlogPost(models.Model):
    text = models.TextField()
    app_data = AppDataField()

您的代码可以在任何(或所有)的AppDataField上注册命名空间并存储 它通过注册一个container(的子类 AppDataContainer)。要定义使用django的表单框架的数据:

from django.forms.models import ModelMultipleChoiceField
from app_data import app_registry, AppDataForm, AppDataContainer

from .models import Tag

class TaggingAppDataForm(AppDataForm):
    public_tags = ModelMultipleChoiceField(Tag.objects.all())
    admin_tags = ModelMultipleChoiceField(Tag.objects.all())

class TaggingAppDataContainer(AppDataContainer):
    form_class = TaggingAppDataForm

    def tag_string(self):
        print ', '.join(t.name for t in self.public_tags)

app_registry.register('tagging', TaggingAppDataContainer)

这将允许您访问任何定义的AppDataField中的'tagging'命名空间:

from blog_app.models import BlogPost

bp = BlogPost()
assert bp.app_data.tagging.tag_string() == ""

其他选项

注意,如果不需要向容器添加自定义方法,可以 只需使用工厂创建子类:

app_registry.register('tagging', AppDataContainer.from_form(TaggingAppDataForm))

此外,您还可以将注册限制为给定的型号:

from blog_app.models import BlogPost

app_registry.register('tagging', TaggingAppDataContainer, BlogPost)

扩展窗体

django-appdata为django的ModelForm提供了一个MultiForm类-a包装。 与注册在 模型的AppDataField,通常可扩展应用程序将创建并使用 MultiForm而不是常规的ModelForm

from app_data.forms import multiform_factory
from .models import BlogPost

BlogPostMultiForm = multiform_factory(BlogPost)

当使用该应用程序时,任何项目都可以在该应用程序中添加其他子表单MultiForm

from blog_app.forms import BlogPostMultiForm

BlogPostMultiForm.add_form('tagging', {'fields': ['public_tags']})

这样当可重用应用程序的代码可以保持不变并且我们可以注入 对其处理的附加形式逻辑。

其他选项

传递任何参数和关键字参数时都不会更改 ModelFormMultiForm正在包装,因此即使您有自定义参数 对于您的ModelForm一切都将继续工作:

from django.forms.models import BaseModelForm

class ModelFormWithUser(ModelForm):
    def __init__(self, user, *args, **kwargs):
        self.user = user
        super(ModelFormWithUser, self).__init__(*args, **kwargs)

BlogPostMultiForm = multiform_factory(BlogPost, form=ModelFormWithUser)

当然,您不限于使用工厂功能:

from app_data import MultiForm

class MyMultiForm(MultiForm):
    ModelForm = BlogPostModelForm

管理中的多种格式

如果您想将自己的代码添加到管理界面,只需使用 AppDataModelAdmin

from django.contrib import admin
from app_data.admin import AppDataModelAdmin
from blog_app.models import BlogPost

class BlogPostAdmin(AppDataModelAdmin):
    # due to the behavior of django admin validation we need to use
    # get_fieldsets instead of just fieldsets
    def get_fieldsets(self, request, obj=None):
         return [
             (None, {'fields': ['text', ]}),
             ('Tagging', {'fields': [('tagging.public_tags', 'tagging.admin_tags')]})
         ]
admin.site.register(BlogPost, BlogPostAdmin)

其他选项

与django的管理和表单一样,您可以通过 使用AppDataModelAdminmultiform属性。

幕后

django-appdata使用TextField在使用json的模型上存储数据 以及django的表单框架,用于数据的(反)序列化和验证。

当访问字段中的容器时,我们将尝试查找 注册表中的相应容器。如果找不到任何数据,则 如果存在则返回(dict)。为确保一切正常工作,我们建议 为您的项目放置某种类型的init代码,以确保 在运行任何实际代码之前完成注册。我们正在使用一个模块 在我们的应用程序中调用register,然后调用类似于管理员的piece of code 自动发现以遍历已安装的应用程序并加载此模块。

生成状态

Master branch:Travis CI - Distributed build platform for the open source community

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java OnResizeListener或OnDrawListener或类似的东西   java Orika映射嵌套子列表   保存时java Heroku请求超时代码H12   数据库在Java中出现socket读取超时异常的原因是什么?   java如何更改来自Sqlite数据库的特定数据在Listview中的行颜色   java JAXB解组器无法正确处理XML中的列表   java Android日期时区让我抓狂   java不透明属性在Swing中如何工作?   eclipse从JavaEE代码生成流程图   java如何在Hibernate中从相关表中获取计数   java Glassfish部署了项目的依赖项库   java使内容适合JavaFx中的WebView   java不满意的链接错误libcrypto。所以1.0.0   循环中java数组的使用   java找出哪个包调用服务