モデルでは、通常、わかりやすい URI の「uuid」フィールドと「slug」フィールドを配置します。
「SomeModel」という名前のモデルがあるとします。その save() メソッドをオーバーライドすることで、保存時に uuid とスラッグを生成できます。
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)
レギュラーモデルでも十分活躍します。今、私は抽象モデルが欲しいです:
class SomeAbstractModel(models.Model):
class Meta:
abstract = True
def save(self, *args, **kwargs):
...
その後:
class SomeModel(SomeAbstractModel):
class Meta(SomeAbstractModel.Meta):
...
問題は、抽象モデルでは、単純に置き換えることができないように見えることです
while SomeModel.objects.filter(uuid=uuid).exists():
と
while SomeAbstractModel.objects.filter(uuid=uuid).exists():
抽象モデルにはマネージャーがいないためです。
この場合、すべてのモデルの save() メソッドで冗長なコードを避けるにはどうすればよいか疑問に思っていました。また、どうかはわかりません
while SomeModel.objects.filter(uuid=uuid).exists():
uuid が存在するかどうかを確認するベスト プラクティスです。