使用django模型表单编辑json字段
django-entangled的Python项目详细描述
django entangled
使用标准django表单编辑json模型字段。
用例
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字段来存储这些任意属性。
fromdjango.dbimportmodelsfromdjango.contrib.postgres.fieldsimportJSONFieldclassProduct(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> }。
fromdjango.contrib.authimportget_user_modelfromdjango.formsimportfields,modelsfromentangled.formsimportEntangledModelFormfrom.modelsimportProductclassProductForm(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),)classMeta:model=Productentangled_fields={'properties':['color','size','tenant']}# fields provided by this formuntangled_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:
fromdjango.contribimportadminfrom.modelsimportProductfrom.formsimportProductForm@admin.register(Product)classProductAdmin(admin.ModelAdmin):form=ProductForm
因为这个ModelAdmin
类使用的表单
can not be created dynamically,
我们必须使用form
属性显式地声明它。这是唯一必须执行的更改,在
以便在json模型字段中存储任意内容。
注意事项
由于JSON的属性,索引和因此基于字段内容构建过滤器或排序规则不是 简单,与标准模型字段相同。因此,如果主要关注的是存储数据, 而不是挖掘数据。
外键存储为json字段中的"fieldname": {"model": "appname.modelname", "pk": 1234}
,这意味着
我们没有数据库限制。如果删除了目标对象,则该外键指向任何地方。因此总是
请记住,我们没有任何引用完整性,因此必须以防御的方式编写代码。
更改
0.3
- 添加支持对于
ModelMultipleChoiceField
。 - 修复方法:在合并之前对
entangled_fields
和untangled_fields
进行深度复制。 - 添加Covenience类
EntangledModelForm
。 - 将数据从纠缠场移到其压缩表示上,现在在
在表单执行了自己的
clean()
之后,访问表单字段就更自然了。 - 添加函数
get_related_object
和get_related_queryset
,以从 json表示。
- 添加支持对于
0.2
- 引入
Meta
-选项untangled_fields
,因为0.1中的方法并不总是有效的。 - 出于可移植性的考虑,使用
formfield()
方法处理django的postgres json字段。
- 引入
0.1
- 初次发布。