在Django模型表单中使用Model属性

akt*_*hor 6 python forms django

我试图使用模型属性,如模型形式中的字段,但到目前为止还没有任何运气.结果是表单只呈现模型字段,而不是我定义的属性.知道如何让表单识别添加到模型中的属性吗?我希望将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
Run Code Online (Sandbox Code Playgroud)

Forms.py:

class InventoryPlotForm(ModelForm):
    class Meta:
        model = ForestInventoryPlot
        exclude = {"geometry"}
Run Code Online (Sandbox Code Playgroud)

ben*_*kji 5

几年后。完整的答案,在 Django 2.2 版本中工作。正如其他人指出的那样,模型表单中仅包含真正的数据库字段。因此,您需要:

  • 定义自定义模型表单,添加您的 @property 字段
  • 排除您的几何字段
  • __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, }
        super().__init__(*args, **kwargs)

    def save(self, *args, **kwargs):
        self.instance.latitude = self.cleaned_data['latitude']
        return super().save(*args, **kwargs)

Run Code Online (Sandbox Code Playgroud)


lan*_*nzz 2

您的属性不是Field实例,因此ModelForm无法自动为其生成表单字段。您需要在表单和方法中显式定义一个latitude字段并管理其检索和更新。或者,您可以实现自己的类并告诉您将其用于该字段:InventoryPlotForm__init__saveWidgetInventoryPlotFormgeometry

class InventoryPlotForm(ModelForm):
    class Meta(object):
        widgets = {
            'geometry': MyGeometryWidget,
        }
        ...
    ...
Run Code Online (Sandbox Code Playgroud)