Django: Populating data into a model based on an identifier
-
23-10-2019 - |
Question
In my Django project, let's say I have the following model:
class City(models.Model):
name = models.CharField(max_length=255)
freebase_id = models.CharField(max_length=255)
latitude = models.DecimalField()
longitude = models.DecimalField()
area = models.IntegerField()
(I've omitted the required parameters for DecimalField for simplicity).
The user could enter all the fields manually, but I want to make life easier by letting the user enter some kind of ID in the admin area, like a Freebase ID (such as /en/manchester_united_kingdom), so that we can then use the API to fetch things like latitude
, longitude
and area
.
Long story short, I want to let users provide some ID which can then be used to derive other data inside the model. In an ideal world, the derived fields should be initially hidden in the admin system, but then made visible once populated so that they can be edited.
Is such a thing possible?
Solution
I am doing something similar in my UserProfile
model. I have a zip code field that, if it gets filled in by the user, is used to do a geo lookup to get city/state and lat/lng and store them in their respective fields in the model:
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
...
zip = models.CharField(max_length=12, blank=True, null=True)
city_state = models.CharField(max_length=30, blank=True, null=True)
lat = models.DecimalField(max_digits=12, decimal_places=9, blank=True, null=True)
lng = models.DecimalField(max_digits=12, decimal_places=9, blank=True, null=True)
def save(self, *args, **kwargs):
if self.zip:
(city_state, lat, lng) = get_lat_lng(self.zip)
if city_state and lat and lng:
self.city_state = city_state
self.lat = lat
self.lng = lng
super(UserProfile, self).save(*args, **kwargs)
class UserProfileForm(ModelForm):
class Meta:
model = UserProfile
fields = ('zip',)
Note that the derived form's zip
field is the only one visible to the user.
OTHER TIPS
If you override the save() method of your object you can set your lat-long in that. Not sure now to hide fields in that way though. There's new stuff in the latest Django for read-only fields, and if you can do that magically via a custom admin manager you might have a way in...