使用django模型表单编辑json字段


django-entangled的Python项目详细描述

django entangled

使用标准django表单编辑json模型字段。

Build Status PyPI PyPI version PyPI Twitter Follow

用例

django模型可以包含接受存储为json的任意数据的字段。Django本身提供了 JSON field特定于Postgres。 对于其他数据库实现,有很多选择。

从模型创建表单时,与json字段关联的输入字段通常是<textarea ...><textarea>。 这个textarea小部件对于编辑来说非常实用,因为它只包含了 对象表示法。一种可能是使用泛型JSON editor, 它使用一些javascript,将小部件转换为属性值对编辑器。然而,这种方法可以防止 我们无法利用django表单框架提供的所有优秀特性,例如字段验证、规范化 数据和外键的使用。通过使用django纠缠,可以使用djangoModelForm,并存储所有, 或者关联模型中一个或多个json字段中的表单字段的子集。

安装

只需安装这个django应用程序,例如通过调用:

pip install django-entangled

不需要向项目的settings.py添加任何配置指令。

示例

比方说,我们有一个django模型来描述一堆不同的产品。有些字段被所有产品使用,而 其他人则描述了这种产品的特性。因为我们不想为每个 产品类型,我们使用json字段来存储这些任意属性。

from django.db import models
from django.contrib.postgres.fields import JSONField

class Product(models.Model):
    name = models.CharField(max_length=50)

    price = models.DecimalField(max_digits=5, decimal_places=2)
    
    properties = JSONField()

在典型的表单编辑视图中,我们将创建一个从 ModelForm并使用 类中的model属性。这里,properties字段将显示为非结构化json呈现 在一个<textarea ...><textarea>里面。这绝对不是我们想要的!相反,我们使用 特殊混合类^ {< CD8> }。

from django.contrib.auth import get_user_model
from django.forms import fields, models
from entangled.forms import EntangledModelForm
from .models import Product

class ProductForm(EntangledModelForm):
    color = fields.RegexField(
        regex=r'^#[0-9a-f]{6}$',
    )

    size = fields.ChoiceField(
        choices=[('s', "small"), ('m', "medium"), ('l', "large"), ('xl', "extra large")],
    )

    tenant = models.ModelChoiceField(
        queryset=get_user_model().objects.filter(is_staff=True),
    )

    class Meta:
        model = Product
        entangled_fields = {'properties': ['color', 'size', 'tenant']}  # fields provided by this form
        untangled_fields = ['name', 'price']  # these fields are provided by the Product model

除了MIXIN类^ {< CD8>},我们还添加了一个特殊的字典,名为{{CD10}} Meta-选项。在这个字典中,键(这里是'properties')引用模型Product中的json字段。 值(这里['color', 'size', 'tenant'])是一个命名表单字段列表,在我们的表单或基类中声明 因此。这允许我们将所有标准django表单字段赋给django中声明的任意json字段。 模型。此外,我们甚至可以使用ModelChoiceField来引用使用 generic relation

因为在这个表单中,我们还想从django模型访问非json字段,所以我们添加了一个名为 untangled_fields到我们的Meta-选项。在这个列表中,(这里['name', 'price'])我们指的是非json字段 在我们的模型中。从这两个迭代器,^ {< CD10> }和^ {CD16> },MIXIN类 EntangledModelFormMixin然后构建Meta-选项fields,否则是必需的。因此没有必要 显式声明此列表。

我们可以在任何django详细视图中使用此表单。一个典型的用例是内置的django modeladmin:

from django.contrib import admin
from .models import Product
from .forms import ProductForm

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    form = ProductForm

因为这个ModelAdmin类使用的表单 can not be created dynamically, 我们必须使用form属性显式地声明它。这是唯一必须执行的更改,在 以便在json模型字段中存储任意内容。

注意事项

由于JSON的属性,索引和因此基于字段内容构建过滤器或排序规则不是 简单,与标准模型字段相同。因此,如果主要关注的是存储数据, 而不是挖掘数据。

外键存储为json字段中的"fieldname": {"model": "appname.modelname", "pk": 1234},这意味着 我们没有数据库限制。如果删除了目标对象,则该外键指向任何地方。因此总是 请记住,我们没有任何引用完整性,因此必须以防御的方式编写代码。

更改

  • 0.3

    • 添加支持对于ModelMultipleChoiceField
    • 修复方法:在合并之前对entangled_fieldsuntangled_fields进行深度复制。
    • 添加Covenience类EntangledModelForm
    • 将数据从纠缠场移到其压缩表示上,现在在 在表单执行了自己的clean()之后,访问表单字段就更自然了。
    • 添加函数get_related_objectget_related_queryset,以从 json表示。
  • 0.2

    • 引入Meta-选项untangled_fields,因为0.1中的方法并不总是有效的。
    • 出于可移植性的考虑,使用formfield()方法处理django的postgres json字段。
  • 0.1

    • 初次发布。

推荐PyPI第三方库


热门话题
webserver lever 微粒 magentoerpconnect iotlab esn nxpy bic ipp emailfield mynt omorfi okpy post32 memory mml lucy sizer freenode manageiq 通信量 waterworks nfd appsettings getsentry xdebug rql starlight suffix j1m scipion pug conference tomo umn ratings androguard apiblueprint haystack dla 滚筒 mig3 pyv8 jeanmichel reactions didery snip logtail mytheme xivapi