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"} ```