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

django-entangled的Python项目详细描述


django entangled

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

Build StatusPyPIPyPI versionPyPITwitter 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字段来存储这些任意属性。

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_fieldsuntangled_fields进行深度复制。
    • 添加Covenience类EntangledModelForm
    • 将数据从纠缠场移到其压缩表示上,现在在 在表单执行了自己的clean()之后,访问表单字段就更自然了。
    • 添加函数get_related_objectget_related_queryset,以从 json表示。
  • 0.2

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

    • 初次发布。

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

推荐PyPI第三方库


热门话题
java如何在堆文件中找到局部变量   java如何使用旧的JSSessionID创建HttpSession?   arrays Java:Arraylist在处理文件时超出范围   可以将Java Retval放入数组中吗   java3d中的几何体碰撞检测?   java从listview和数据库中删除项   Java迭代两个列表,比较然后添加到另一个列表   java应用程序在提交分数排行榜Google Play时崩溃   java Eclipse+Maven Plugin+EGit Plugin=从GitHub签出特定的分支和标记?   Java中的半密码保护Zip文件   java JFrame组件能够通过重绘调用paintComponent,尽管使用flowlayout   带有比较器的Lambda表达式中的java Stream min()和max()方法只返回第一个和最后一个元素,不返回min/max元素   swing Java/Netbeans:JList。getModel()返回一个ListModel而不是DefaultListModel   java我如何使用应用程序。带有LiveData和ViewModel的片段   地理定位在Java中获取用户当前的纬度和经度   为什么在Java中将“this”用作方法参数时会收到此错误消息?   java将字符串转换为JSONArray(或任何数组)