我试图使用模型属性,比如模型表单中的字段,但到目前为止还没有任何运气。结果是表单只呈现模型字段,而不是我定义的属性。知道如何让表单识别添加到模型中的属性吗?我希望将latitude属性添加为表单中的另一个字段。
Models.py:
class Plot(models.Model):
plot_id = models.AutoField(primary_key=True)
plot_number = models.IntegerField(validators=[MinValueValidator(1)], null=False, unique=True)
geometry = models.PointField(srid=2163, null=True, blank=True)
objects = models.GeoManager()
@property
def latitude(self):
self.geometry.transform(4326)
return self.geometry.y
@latitude.setter
def latitude(self, latitude):
self.geometry.y = latitude
Forms.py:
class InventoryPlotForm(ModelForm):
class Meta:
model = ForestInventoryPlot
exclude = {"geometry"}
答案 0 :(得分:3)
您的属性不是Field
实例,因此ModelForm
无法自动为其生成表单字段。您需要在latitude
上明确定义InventoryPlotForm
字段,并使用表单的__init__
和save
方法管理其检索和更新。或者,您可以实施自己的Widget
课程,并告诉InventoryPlotForm
将其用于geometry
字段:
class InventoryPlotForm(ModelForm):
class Meta(object):
widgets = {
'geometry': MyGeometryWidget,
}
...
...
答案 1 :(得分:1)
ModelForm只会自动生成Django字段。
例如:
class InventoryPlotForm(ModelForm):
latitude = forms.CharField(max_length=52) # Something like this
def save(self, commit=True):
model_instance = super(InventoryPlotForm, self).save(commit=False)
result = super(InventoryPlotForm, self).save(commit=True)
model_instance.latitude = self.cleaned_data['latitude']
model_instance.save()
return result
class Meta:
model = ForestInventoryPlot
widgets = {'geometry': HiddenInput()}
在您的视图中
...
form = InventoryPlotForm(instance=forestinventoryplot,
initial={"latitude":forestinventoryplot.latitude})
...
答案 2 :(得分:0)
几年后。一个完整的答案,可以在Django 2.2或更高版本中使用。正如其他人指出的那样,模型形式中仅包含实际的db字段。因此,您需要:
__init__
中,获取值,并将其设置为initial
。注意:这在更复杂的情况下也适用,在这种情况下,您想抽象出一些更复杂的数据库结构...
class InventoryPlotForm(ModelForm):
class Meta:
model = ForestInventoryPlot
exclude = ("geometry", )
latitude = forms.WhateverField()
def __init__(self, *args, **kwargs):
instance = kwargs.get('instance', None)
if instance:
kwargs['initial'] = {'latitude': instance.latitude, }
return super().__init__(*args, **kwargs)
def save(self, *args, **kwargs):
self.instance.latitude = self.cleaned_data['latitude']
return super().save(*args, **kwargs)