いくつかの理由により^、DjangoモデルのいくつかでUUIDを主キーとして使用したいと思います。その場合、ContentTypeを介した一般的な関係を使用する「contrib.comments」、「Django-voting」、「Django-tagging」などの外部アプリを引き続き使用できますか?
「Django-voting」を例として使用すると、投票モデルは次のようになります。
class Vote(models.Model):
user = models.ForeignKey(User)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
object = generic.GenericForeignKey('content_type', 'object_id')
vote = models.SmallIntegerField(choices=SCORES)
このアプリは、投票されるモデルの主キーが整数であると想定しているようです。
ただし、組み込みのコメントアプリは、整数ではないPKを処理できるようです。
class BaseCommentAbstractModel(models.Model):
content_type = models.ForeignKey(ContentType,
verbose_name=_('content type'),
related_name="content_type_set_for_%(class)s")
object_pk = models.TextField(_('object ID'))
content_object = generic.GenericForeignKey(ct_field="content_type", fk_field="object_pk")
この「integer-PK-assumed」問題は、UUIDを使用するのが面倒になるサードパーティアプリの一般的な状況ですかまたは、おそらく、私はこの状況を誤解していますか?
Djangoで主キーとしてUUIDを使用する方法はありますか?
UUIDの主キーは、一般的な関係だけでなく、一般的な効率でも問題を引き起こします。すべての外部キーは、マシンのWordよりもはるかに高価です(格納および参加の両方)。
ただし、UUIDを主キーにする必要はありません。モデルをunique=True
でuuidフィールドで補完することで、secondaryキーにするだけです。暗黙の主キーを通常どおり(システムの内部)使用し、UUIDを外部識別子として使用します。
ドキュメントに記載されているように 、from Django 1.8にはUUIDフィールドが組み込まれています。UUIDと整数を使用した場合のパフォーマンスの違いはごくわずかです。
import uuid
from Django.db import models
class MyUUIDModel(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
この回答を確認 で詳細を確認することもできます。
私は同様の状況に遭遇し、 official Django documentation で、object_id
は、関連するモデルのprimary_keyと同じ型である必要はありません。たとえば、ジェネリック関係をIntegerFieldとCharFieldidの両方に対して有効にしたい場合は、object_id
は、CharFieldになります。整数は強制的に文字列に変換できるため、問題ありません。 UUIDFieldについても同様です。
例:
class Vote(models.Model):
user = models.ForeignKey(User)
content_type = models.ForeignKey(ContentType)
object_id = models.CharField(max_length=50) # <<-- This line was modified
object = generic.GenericForeignKey('content_type', 'object_id')
vote = models.SmallIntegerField(choices=SCORES)