In a model I usually put a "uuid" field for friendly URI, also a "slug" field.
Say I have a model named "SomeModel", by overriding its save() method, I can generate a uuid and a slug when it's being saved:
class SomeModel(models.Model):
...
def save(self, *args, **kwargs):
if not self.uuid:
uuid = shortuuid.uuid()[:10]
while SomeModel.objects.filter(uuid=uuid).exists():
uuid = shortuuid.uuid()[:10]
self.uuid = uuid
if not self.slug:
self.slug = slugify(self.title)[:500].rstrip('-')
super(SomeModel, self).save(*args, **kwargs)
It works well on regular model. Now I'd like to have an abstract model:
class SomeAbstractModel(models.Model):
class Meta:
abstract = True
def save(self, *args, **kwargs):
...
And then:
class SomeModel(SomeAbstractModel):
class Meta(SomeAbstractModel.Meta):
...
The problem is, in the abstract model, looks like I cannot just simply replace
while SomeModel.objects.filter(uuid=uuid).exists():
with
while SomeAbstractModel.objects.filter(uuid=uuid).exists():
because abstract model doesn't have a manager.
I was wondering in this case, how can I avoid having redundant code in all models' save() methods. Also I'm not sure if
while SomeModel.objects.filter(uuid=uuid).exists():
is the best practice to check if an uuid exists or not.
Not sure if it is the prettiest way in town but this should work:
while self.__class__.objects.filter(...):
pass