【问题标题】:Django custom form with non-model fields in Admin/AdminInline在 Admin/AdminInline 中具有非模型字段的 Django 自定义表单
【发布时间】:2014-12-20 17:35:38
【问题描述】:

我在自定义 Django 管理页面以使用自定义表单或非模型字段时遇到了一些麻烦。

我正在开发的网站将用作数据存储实用程序,用于报告某些制造过程。该数据库将具有三个主表,其中两个将在第四个表中具有 ForeignKey。第四个表中的每一行本质上是需要上传的 CSV 文件中的一行。第四个表的模型如下所示:

bandwidthrawid = models.IntegerField(...) 
testdate = models.DateTimeField(...)
frequency = models.FloatField(...)
power = models.FloatField(...)
uncalibratedpower = models.FloatField(...)

我让 Django 自动生成 id 字段。对于同一测试中的每个条目,测试日期将是静态的。 Frequency、Power 和 UncalibratedPower 字段都将包含来自 CSV 文件同一行的单个值。 BandwidthRawId 字段将包含按顺序排列的整数,多次重复指示这是哪个特定测试。因此,例如,假设用户在 1 到 60 Hz 的频率范围内以 1 Hz 的步长测试同一模块两次,将生成一个类似于以下内容的 CSV 文件:

1,0,0
2,0,0
3,0,0
4,0,0
5,0,0
...
60,0,0

第二个测试也会生成一个类似的文件。当这些文件上传到系统中时,将记录测试的日期,并为其分配一个 BandwidthRawId,这是该列中当前最高值的增量值。因此,这两个文件的表条目将如下所示:

Id, Date, BWID, F, P, UP
1,  Date1, 1,   1, 0, 0
2,  Date1, 1,   2, 0, 0
...
60,  Date1, 1,   60, 0, 0
61,  Date2, 2,   1, 0, 0
62,  Date2, 2,   2, 0, 0
...
120,  Date2, 2,   60, 0, 0

这就是事情开始变得棘手的地方。有时文件的顺序不同,因此 CSV 导入器无法工作。有时文件不包含所有正确的信息。这些文件中永远不会有日期,也永远不会有任何标题行。为了解决所有这些问题,我创建了一个小部件/字段,用于创建 CSV 预览并允许用户选择每列所属的实际字段。我将此称为 CSVPreviewField。

为了在“字段”中测试此字段/小部件,我覆盖了模型中的 BandwidthRawID 字段,并使用它来处理所有处理。最初我认为覆盖该字段,进行处理,然后用正确的整数填充该字段,然后将其传递给处理会很容易。不幸的是,这不起作用。我收到 BandwidthRawID 字段类型无效的错误(在数据库中它是一个整数,在模型中它是 CSVPreviewField/FileInput)。

接下来,我尝试将 CSVPreviewField(称为 BandwidthRawFile)添加到使用 BandwidthRaw 作为模型的 ModelForm 中,并覆盖了我为处理 bandwidth_raw 表而编写的 ModelAdmin 类的表单字段。不幸的是,无论我做什么,我都无法显示这个字段,我得到的错误是“在表单字段中找不到 BandwidthRawFile”或类似的东西。我还收到一个错误,表明数据库中没有与“BandwidthRawFile”对应的列。

在那之后,我了解了内联,并尝试使用内联表单做同样的事情,但由于类似的原因也失败了。要么失败,因为我没有指定模型(希望我可以做一个自定义表单),模型不包含 BandwidthRawFile 字段,或者数据库不包含该字段。

此时,我已经为此工作了两天,并且完全没有想法。基本上,内联表单将是最好的解决方案。如果我可以以某种方式将我的小部件内联到需要 BandwidthRawId 的另外两个管理页面中,然后作为小部件处理的结果返回该值,那将是理想的情况。现在我很高兴让外键旁边的小绿色 + 启动一个自定义表单,该表单执行所有处理并返回 BandwidthRawId。

【问题讨论】:

  • 这个问题包含太多与制造过程和代词相关的细节,而与 Django 和小部件的相关性太少。问题不清楚。例如,BandwidthRawIdbandwidthrawid 有何不同?
  • 那些字段并没有什么不同。 Django 自动将 SQL 字段名称更改为小写。

标签: python django django-models django-forms django-admin


【解决方案1】:

由于看起来没有人对此有答案,我将继续“回答”它。

我找到的答案是模型表单中不能有非模型字段。它们被框架简单地忽略了。添加您自己的内联表单似乎也效果不佳,最终会发生相同的错误。

我解决这个问题的方法是:

  1. 创建 CSV 预览小部件
  2. 将小部件实现到 CSV 字段中
  3. 编写字段/小部件逻辑
  4. 创建我自己的表单——不是模型表单
  5. 创建表单处理程序
  6. 创建视图以承载表单
  7. 覆盖模型中的 add_view 以返回自定义表单
  8. 覆盖模型中的 get_form 函数以将 csv 小部件添加到表单中

我不太喜欢这个答案,但我没有更好的解决方案。

【讨论】:

    【解决方案2】:

    如果你对实现不太挑剔,你可能想看看 Postgres Foreign data wrappers 之类的东西(file_fdw 是一个 csv 接口)。由于文件非常统一,您将获得一个不错的 ORM 界面,并在导入方面省去很多麻烦。

    【讨论】:

    • 很遗憾,我们的 CSV 文件根本不统一。如果这只是一个简单的一次性问题,我会做类似于您建议的事情,但这些文件每天都会生成,技术人员需要一个简单的界面来将数据放入系统。
    猜你喜欢
    • 2012-12-11
    • 1970-01-01
    • 2021-10-13
    • 2011-06-15
    • 2011-06-12
    • 2015-06-13
    • 1970-01-01
    • 1970-01-01
    • 2012-08-21
    相关资源
    最近更新 更多