首页 文章

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

提问于
浏览
3

我在定制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导入器不起作用 . 有时文件不包含所有正确的信息 . 文件永远不会有日期,并且永远不会有任何 Headers 行 . 为了解决所有这些问题,我创建了一个窗口小部件/字段,用于创建CSV预览,并允许用户选择每列所属的实际字段 . 我调用了这个CSVPreviewField .

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

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

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

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

2 回答

  • 0

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

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

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

    • 创建CSV预览小组件

    • 将Widget实现为CSV字段

    • 编写字段/窗口小部件逻辑

    • Create my own form -- NOT a model-form

    • 创建表单处理程序

    • 创建托管表单的视图

    • 覆盖模型中的add_view以返回自定义表单

    • 覆盖模型中的get_form函数,将csv小部件添加到表单中

    我真的不喜欢 - 这个答案,但我没有更好的解决方案 .

  • 3

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

相关问题