将自定义字段添加到django模型(不更改源代码)

时间:2022-01-18 22:58:12

A customer wants to add custom fields to a django model we provide.

客户想要将自定义字段添加到我们提供的django模型中。

He wants to do this on his own, without programming.

他想在没有编程的情况下独自完成这项工作。

These things should be addable:

这些东西应该是可以添加的:

  • boolean (yes/no) fields. Optional "unset"
  • 布尔值(是/否)字段。可选“未设置”
  • single choice fields
  • 单选领域
  • multiple choice fields
  • 多选字段
  • single line text fields
  • 单行文本字段
  • textarea fields
  • textarea字段
  • date
  • 日期

Example:

例:

The customer wants to add a field he calls "was successful". And the field > should have these choices: yes/no/unset. Defaulting to unset.

客户想要添加一个他称之为“成功”的字段。字段>应该有这些选择:是/否/未设置。默认未设置。

Things would be easy if I could do it by creating or extending a model. But in this case no source code changes are allowed :-(

如果我可以通过创建或扩展模型来实现这一目标,那将会很容易。但在这种情况下,不允许更改源代码:-(

How to solve this?

怎么解决这个?

Update

更新

Querying for instances with given values needs to be supported. Example: Show all instances where "was successful" is True.

需要支持查询具有给定值的实例。示例:显示“成功”为True的所有实例。

6 个解决方案

#1


7  

You can create a table that follows the EAV principle (Entity Attribute Value). Basically this is a denormalised table with following columns:
[ID (and/or slug), float_value, integer_value, string_value] (Add more columns to this table)

您可以创建遵循EAV原则(实体属性值)的表。基本上这是一个带有以下列的非规范化表:[ID(和/或slug),float_value,integer_value,string_value](向此表添加更多列)

Now say you've a existing table called "Member". When customer adds a dynamic field via your UI, you add the entries here and use "ID" to look them up for a given member.

现在说你有一个名为“会员”的现有表。当客户通过您的UI添加动态字段时,您可以在此处添加条目并使用“ID”查找给定成员。

#2


2  

I use Django Dynamic Forms. Out of the box, it lets users create their own forms through the admin. You might want to extend it to build a more user-friendly UI, but this should get you pretty far. It supports

我使用Django Dynamic Forms。开箱即用,它允许用户通过管理员创建自己的表单。您可能希望扩展它以构建更加用户友好的UI,但这应该会让您相当远。它支持

  • boolean
  • 布尔
  • choices (select)
  • 选择(选择)
  • multiple choices (multiple select)
  • 多种选择(多选)
  • date
  • 日期
  • datetime
  • 约会时间
  • time
  • 时间
  • email
  • 电子邮件
  • integer
  • 整数
  • single line text
  • 单行文字
  • multi line text
  • 多行文字

#3


2  

Well, when I had such problem, I used to create a custom field model, with a name field and a type field, usually a choice field with choices for the possible field types. You can also add a is_active field to filter the active and inactive CustomFields.

好吧,当我遇到这样的问题时,我曾经创建了一个自定义字段模型,带有一个名称字段和一个类型字段,通常是一个选择字段,可以选择可能的字段类型。您还可以添加is_active字段以过滤活动和非活动CustomField。

Than, when I create the for, I search this objects to know which fields I must have in that form.

当我创建for时,我搜索这些对象以了解我必须在该表单中包含哪些字段。

To store the data, I'd have another model, called CustomFieldAnswer, or somethink like this. This model should have a ForeignKey to the main model that should have this data, and the custom field.

为了存储数据,我有另一个名为CustomFieldAnswer的模型,或者像这样的一些思考。此模型应具有应具有此数据的主模型的ForeignKey和自定义字段。

Doing so, You can have any kinds of fields for yout model dinamically and wothout you client needing to code anything.

这样做,你可以为你的模型提供任何类型的字段,并且客户需要编写任何代码。

You could use metaprogramming to create acutual fields in a form based on the query in the CustomFields. Or, you could just put the fields in the template and change the type of the input for each CustomField.

您可以使用元编程基于CustomFields中的查询在表单中创建实际字段。或者,您可以将字段放在模板中,并更改每个CustomField的输入类型。

Hope that helps!

希望有所帮助!

#4


0  

If that's really what you want.

如果这真的是你想要的。

  1. Create enough fields that your customer ever need.

    创建客户所需的足够字段。

    boolean_field_1 = models.BooleanField(..)
    boolean_field_2 ..
    date_field_1 = ..
    date_field_2 = ..
    
  2. Store alias mapping somewhere.

    在某处存储别名映射。

    I could add a field for alias mapping.

    我可以为别名映射添加一个字段。

    json_mapping_field = JSONField()
    # this has is_successful: boolean_field_1
    
  3. Then find places where you can substitute the alias back to the real field name

    然后找到可以将别名替换回真实字段名称的位置

    for simple filter and update, you could override

    对于简单的过滤和更新,您可以覆盖

    1. QuerySet.filter Queryset.exclude
    2. QuerySet.filter Queryset.exclude
    3. QuerySet.update, UpdateQuery.add_update_values
    4. QuerySet.update,UpdateQuery.add_update_values
    5. finally use from_queryset for your manager to use the overidden QuerySet.
    6. 最后使用from_queryset为您的经理使用重叠的QuerySet。

#5


0  

I know it sounds like an awful hack, but maybe you can build an interface that creates text files?

我知道这听起来像是一个糟糕的黑客,但也许你可以构建一个创建文本文件的界面?

  1. One file would be models.py, with model definitions, and excluding this model from migrations with managed = False
  2. 一个文件是models.py,带有模型定义,并且使用managed = False从迁移中排除此模型
  3. Another file is the SQL with DROP and CREATE table if the customer wants a new table, or just ALTER table.
  4. 如果客户想要一个新表,或者只是ALTER表,则另一个文件是带有DROP和CREATE表的SQL。
  5. Another script can run the SQL script, copy the models.py file to the correct directory, and reload django.
  6. 另一个脚本可以运行SQL脚本,将models.py文件复制到正确的目录,然后重新加载django。

#6


0  

I just discovered, that there is even a comparison grid on djangopackages about this:

我刚刚发现,djangopackages上甚至还有一个比较网格:

https://www.djangopackages.com/grids/g/dynamic-models/

https://www.djangopackages.com/grids/g/dynamic-models/

Heading:

标题:

Apps to add fields to models in the settings, or even at runtime.

用于在设置中或甚至在运行时向模型添加字段的应用程序。

Some * administrator deleted this answer, that's why I write it again.

一些*管理员删除了这个答案,这就是我再次写它的原因。

Reason of deletion was:

删除原因是:

While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes.

虽然此链接可能会回答这个问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面发生更改,则仅链接答案可能会变为无效。

Here are the current packages which are listed on the comparison grid today:

以下是今天在比较网格上列出的当前包:

#1


7  

You can create a table that follows the EAV principle (Entity Attribute Value). Basically this is a denormalised table with following columns:
[ID (and/or slug), float_value, integer_value, string_value] (Add more columns to this table)

您可以创建遵循EAV原则(实体属性值)的表。基本上这是一个带有以下列的非规范化表:[ID(和/或slug),float_value,integer_value,string_value](向此表添加更多列)

Now say you've a existing table called "Member". When customer adds a dynamic field via your UI, you add the entries here and use "ID" to look them up for a given member.

现在说你有一个名为“会员”的现有表。当客户通过您的UI添加动态字段时,您可以在此处添加条目并使用“ID”查找给定成员。

#2


2  

I use Django Dynamic Forms. Out of the box, it lets users create their own forms through the admin. You might want to extend it to build a more user-friendly UI, but this should get you pretty far. It supports

我使用Django Dynamic Forms。开箱即用,它允许用户通过管理员创建自己的表单。您可能希望扩展它以构建更加用户友好的UI,但这应该会让您相当远。它支持

  • boolean
  • 布尔
  • choices (select)
  • 选择(选择)
  • multiple choices (multiple select)
  • 多种选择(多选)
  • date
  • 日期
  • datetime
  • 约会时间
  • time
  • 时间
  • email
  • 电子邮件
  • integer
  • 整数
  • single line text
  • 单行文字
  • multi line text
  • 多行文字

#3


2  

Well, when I had such problem, I used to create a custom field model, with a name field and a type field, usually a choice field with choices for the possible field types. You can also add a is_active field to filter the active and inactive CustomFields.

好吧,当我遇到这样的问题时,我曾经创建了一个自定义字段模型,带有一个名称字段和一个类型字段,通常是一个选择字段,可以选择可能的字段类型。您还可以添加is_active字段以过滤活动和非活动CustomField。

Than, when I create the for, I search this objects to know which fields I must have in that form.

当我创建for时,我搜索这些对象以了解我必须在该表单中包含哪些字段。

To store the data, I'd have another model, called CustomFieldAnswer, or somethink like this. This model should have a ForeignKey to the main model that should have this data, and the custom field.

为了存储数据,我有另一个名为CustomFieldAnswer的模型,或者像这样的一些思考。此模型应具有应具有此数据的主模型的ForeignKey和自定义字段。

Doing so, You can have any kinds of fields for yout model dinamically and wothout you client needing to code anything.

这样做,你可以为你的模型提供任何类型的字段,并且客户需要编写任何代码。

You could use metaprogramming to create acutual fields in a form based on the query in the CustomFields. Or, you could just put the fields in the template and change the type of the input for each CustomField.

您可以使用元编程基于CustomFields中的查询在表单中创建实际字段。或者,您可以将字段放在模板中,并更改每个CustomField的输入类型。

Hope that helps!

希望有所帮助!

#4


0  

If that's really what you want.

如果这真的是你想要的。

  1. Create enough fields that your customer ever need.

    创建客户所需的足够字段。

    boolean_field_1 = models.BooleanField(..)
    boolean_field_2 ..
    date_field_1 = ..
    date_field_2 = ..
    
  2. Store alias mapping somewhere.

    在某处存储别名映射。

    I could add a field for alias mapping.

    我可以为别名映射添加一个字段。

    json_mapping_field = JSONField()
    # this has is_successful: boolean_field_1
    
  3. Then find places where you can substitute the alias back to the real field name

    然后找到可以将别名替换回真实字段名称的位置

    for simple filter and update, you could override

    对于简单的过滤和更新,您可以覆盖

    1. QuerySet.filter Queryset.exclude
    2. QuerySet.filter Queryset.exclude
    3. QuerySet.update, UpdateQuery.add_update_values
    4. QuerySet.update,UpdateQuery.add_update_values
    5. finally use from_queryset for your manager to use the overidden QuerySet.
    6. 最后使用from_queryset为您的经理使用重叠的QuerySet。

#5


0  

I know it sounds like an awful hack, but maybe you can build an interface that creates text files?

我知道这听起来像是一个糟糕的黑客,但也许你可以构建一个创建文本文件的界面?

  1. One file would be models.py, with model definitions, and excluding this model from migrations with managed = False
  2. 一个文件是models.py,带有模型定义,并且使用managed = False从迁移中排除此模型
  3. Another file is the SQL with DROP and CREATE table if the customer wants a new table, or just ALTER table.
  4. 如果客户想要一个新表,或者只是ALTER表,则另一个文件是带有DROP和CREATE表的SQL。
  5. Another script can run the SQL script, copy the models.py file to the correct directory, and reload django.
  6. 另一个脚本可以运行SQL脚本,将models.py文件复制到正确的目录,然后重新加载django。

#6


0  

I just discovered, that there is even a comparison grid on djangopackages about this:

我刚刚发现,djangopackages上甚至还有一个比较网格:

https://www.djangopackages.com/grids/g/dynamic-models/

https://www.djangopackages.com/grids/g/dynamic-models/

Heading:

标题:

Apps to add fields to models in the settings, or even at runtime.

用于在设置中或甚至在运行时向模型添加字段的应用程序。

Some * administrator deleted this answer, that's why I write it again.

一些*管理员删除了这个答案,这就是我再次写它的原因。

Reason of deletion was:

删除原因是:

While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes.

虽然此链接可能会回答这个问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面发生更改,则仅链接答案可能会变为无效。

Here are the current packages which are listed on the comparison grid today:

以下是今天在比较网格上列出的当前包: