使用UUID作为Django模型中的主键(通用关系影响) [英] Using a UUID as a primary key in Django models (generic relations impact)
问题描述
由于很多原因^,我想在一些Django模型中使用UUID作为主键。如果我这样做,我仍然可以使用外部应用程序,如contrib.comments,django-voting或django-tagging,它们通过ContentType使用通用关系?
For a number of reasons^, I'd like to use a UUID as a primary key in some of my Django models. If I do so, will I still be able to use outside apps like "contrib.comments", "django-voting" or "django-tagging" which use generic relations via ContentType?
使用django-voting作为示例,投票模型如下所示:
Using "django-voting" as an example, the Vote model looks like this:
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)
应用程序似乎假设投票模型的主键是一个整数。
This app seems to be assuming that the primary key for the model being voted on is an integer.
内置评论应用程序似乎有能力处理非整数PK,但是:
The built-in comments app seems to be capable of handling non-integer PKs, though:
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")
这个整数PK假设问题是第三方应用程序的常见情况,这将使使用UUID疼痛?或者可能我误解了这种情况?
Is this "integer-PK-assumed" problem a common situation for third-party apps which would make using UUIDs a pain? Or, possibly, am I misreading this situation?
有没有办法将UUID用作Django中的主键,而不会造成太多麻烦?
Is there a way to use UUIDs as primary keys in Django without causing too much trouble?
^一些原因:隐藏对象计数,阻止urlid抓取,使用多个服务器创建非冲突对象,...
^ Some of the reasons: hiding object counts, preventing url "id crawling", using multiple servers to create non-conflicting objects, ...
推荐答案
UUID主键不仅会导致通用关系的问题,而且通常会带来效率:每个外键都会显着更昂贵存储和加入机器字。
A UUID primary key will cause problems not only with generic relations, but with efficiency in general: every foreign key will be significantly more expensive—both to store, and to join on—than a machine word.
但是,无需UUID作为主键:只需将其设为辅助键,通过用 unique = True
的uuid字段补充您的模型。使用隐式主键(正常(系统内部)),并使用UUID作为外部标识符。
However, nothing requires the UUID to be the primary key: just make it a secondary key, by supplementing your model with a uuid field with unique=True
. Use the implicit primary key as normal (internal to your system), and use the UUID as your external identifier.
这篇关于使用UUID作为Django模型中的主键(通用关系影响)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!