I have a problem to define Django model where the Primary Key is UUID5 that base on model fields.
Here is what I have got already.
class Place(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid5('PLACE_UUID_NAMESPACE', '{}{}{}'.format(self.city, self.zip, self.country)))
city = models.CharField(max_length=24, blank=True, null=True)
zip = models.CharField(max_length=6, blank=True, null=True)
country = CountryField(default="US")
The problem is with referring to model field as I did self.city, self.zip, self.country
. Django does not accept the way I did.
How can I define the uuid5 using model fields?
I appreciate your help.
The problem is with referring to model field as I did
self.city
,self.zip
,self.country
. Django does not accept the way I did.
Yes and Django is right. You do not have an access to self
yet until you have an instance of the class. So try this instead:
class Place(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4)
•••
So that if we instantiate an instance with for example:
aPlace = Place(city=“Bournemouth”, zip=“blah”)
Now we have aPlace
Which has by default, a random but unique identifier (UUID) in it’s uuid
field and a CountryField(default="US")
in it’s country
field. Also city
field is “Bournemouth”
, and zip
is “blah”
.
Then you can manipulate the instance right before saving to database. That is where you change certain fields for example the uuid
field.
aPlace.uuid = uuid.uuid5('PLACE_UUID_NAMESPACE', '{}{}{}'.format(aPlace.city, aPlace.zip, aPlace.country))
aPlace.save()
Or directly override the save method of the model:
def save(self, *args, **kwargs):
self.uuid = uuid.uuid5('PLACE_UUID_NAMESPACE', '{}{}{}'.format(self.city, self.zip, self.country))
super().save(*args, **kwargs)
Don’t think that’s possible, since you don’t have access to the instance from the callable default argument.
Your best chance is to set random default uuid and use pre save signal to override it with what you want.