Django自定义表单,包含Admin / AdminInline中的非模型字段

时间:2014-10-24 20:02:22

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

我在定制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赫兹的频率范围内以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)。

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

之后,我学习了内联,并尝试使用内联形式进行同样的操作,但由于类似的原因,它也失败了。要么失败,因为我没有指定模型(希望我可以做自定义表单),模型不包含BandwidthRawFile字段,或者数据库不包含该字段。

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

2 个答案:

答案 0 :(得分:3)

由于看起来没有人对此有答案,我会继续前进并回答"它。

我发现的答案是你不能在模型中使用非模型字段。它们完全被框架忽略了。内联添加自己的表单似乎也不能正常工作,最终会出现相同的错误。

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

  1. 创建CSV预览小组件
  2. 将小部件实施为CSV字段
  3. 编写字段/窗口小部件逻辑
  4. 创建自己的表单 - 不是模型表单
  5. 创建表单处理程序
  6. 创建视图以托管表单
  7. 覆盖模型中的add_view以返回自定义表单
  8. 覆盖模型中的get_form函数,将csv小部件添加到表单
  9. 我真的不喜欢这个答案,但我没有更好的解决方案。

答案 1 :(得分:0)

如果您对实现不太挑剔,可能需要查看Postgres Foreign data wrappers之类的内容(file_fdw是csv接口)。由于文件非常统一,您将获得一个漂亮的ORM界面,并在导入方面节省大量的麻烦。