Use Model Property in a Django Model Form

django, forms, python

Solution

Some years later. A complete answer, working in Django up to 2.2. As others have pointed out, only real db fields are included in the model form. So, you'll need to:

- Define a custom model form, add your @property field

- Exclude your geometry field

- In the `__init__` of the form, get the value, and set it as `initial`.

- Customize your save method (on the form or admin)

Note: This works also in more complex cases, where you want to abstract away some more complex database structure...

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)

Problem

I am attempting to use model properties like fields within a model form, but so far haven't had any luck. The result is that the form renders only the model fields, and not the property I defined. Any idea how to get the form to recognize the property added to the model? I expect to see the latitude property added as just another field in the form. 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"} ```

Original source