Django 将额外字段添加到从模型生成的 ModelForm

Posted

技术标签:

【中文标题】Django 将额外字段添加到从模型生成的 ModelForm【英文标题】:Django add extra field to a ModelForm generated from a Model 【发布时间】:2012-11-13 02:00:34 【问题描述】:

我必须从模型生成一个 FormSet,但我需要在每个表单中插入一个“额外值”。

具体来说,我有一个 JApplet,它可以在图像上生成一些标记和路径,并将其发布到服务器上。

在我的模型中,线条由两个标记组成。但是当我发布它时,因为我使用的是从 JApplet 而不是从数据库生成的 id,所以我不知道路径将由哪些标记组成。

所以我想在表单的Marker上插入一个“临时id”,并在保存路径之前在视图中做正确的排列。

我想过为标记定义一个自定义表单,但它似乎不是很干燥,如果我更改标记模型,我不想回到这个问题。

这是表格:

  class PointForm(forms.ModelForm):
    temp_id = forms.IntegerField()
    class Meta:
            model = Point

    def clean(self):
            if any(self.errors):
                    # Don't bother validating the formset unless each form is valid on its own
                    return

            ingresso = self.cleaned_data['ingresso']
            ascensore = self.cleaned_data['ascensore']
            scala = self.cleaned_data['scala']

            if (ingresso and ascensore) or (ingresso and scala) or (ascensore and scala):
                    raise forms.ValidationError("A stair cannot be a elevator or an access!!!") 
            return self

    def save(commit=True):
    # do something with self.cleaned_data['temp_id']
            super(PointForm).save(commit=commit)

还有模特:

  class Point(models.Model):

    RFID = models.CharField(max_length=200, blank=True)

    x = models.IntegerField()
    y = models.IntegerField()

    piano = models.ForeignKey(Floor)

    ingresso = models.BooleanField()

错误:

  ViewDoesNotExist at /admin/
  Could not import buildings.views.getFloors. View does not exist in module buildings.views.
  Request Method:   GET
  Request URL:  http://127.0.0.1:8000/admin/
  Django Version:   1.4.1
  Exception Type:   ViewDoesNotExist
  Exception Value:  
  Could not import buildings.views.getFloors. View does not exist in module buildings.views.
  Exception Location:   /usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py in get_callable, line 101

当我尝试加载管理页面时产生错误,该页面根本没有与表单的引用。

异常解决方案

好的,我将在这里写下如何找出 Django 为什么会做这么奇怪的事情。

Here 这是找出问题所在的正确方法。

抛出异常是因为我忘记将forms.py 添加到from django import forms

【问题讨论】:

而且,如果我从 url.py 中删除 getFloors 它会在下一个 url 上调用 missing view 错误在 url.py... 这是一个错误吗? 【参考方案1】:

您可以向 ModelForm 添加字段。除非您在模型中添加一个名为 temp_id 的字段,否则您在更改模型时不需要更改此表单。

示例(使用名为 Point 的模型):

class PointForm (forms.ModelForm):
    temp_id = forms.IntegerField()

    class Meta:
        model = Point

    def save(self, commit=True):
        # do something with self.cleaned_data['temp_id']
        return super(PointForm, self).save(commit=commit)

更新:在 def save() 中忘记了 self 并将模型名称更改为 Point

【讨论】:

我在@relekang 之前尝试过这种方法,但我得到一个无法导入buildings.views.getFloors。视图在模块 building.views 中不存在。 当我删除 temp_id = forms.IntegerField() 行时,一切正常...... 看起来您在循环导入方面遇到了问题。 不知何故这样做导致我的clean 方法没有运行,我不知道为什么。呃。【参考方案2】:

为了跟进 relekang 的回答,我不得不提醒我最后一行 return 如图所示,以便在提交表单时自动调用对象的 get_absolute_url() 方法:

return super(PointForm, self).save(commit=commit)

【讨论】:

以上是关于Django 将额外字段添加到从模型生成的 ModelForm的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 django 向默认 auth_user 模型添加额外的模型字段

将字段添加到从 Mongoose 模式派生的模型

Django 中的动态模型字段

Django:为可重用模型字段创建一个 Mixin

在 django 中向 QuerySet 添加 ManyToMany 额外字段

在 django 的多对多关系中添加额外的字段