Django 我应该使用ArrayField还是ManyToManyField作为标记

Django 我应该使用ArrayField还是ManyToManyField作为标记,django,postgresql,django-models,django-postgresql,Django,Postgresql,Django Models,Django Postgresql,我试图在django中为postgres db的模型添加标记,我发现了两种解决方案: 使用外键: class Post(models.Model): tags = models.ManyToManyField('tags') ... class Tag(models.Model): name = models.CharField(max_length=140) 使用数组字段: from django.contrib.postgres.fields import Arr

我试图在django中为postgres db的模型添加标记,我发现了两种解决方案:

使用外键:

class Post(models.Model):
    tags = models.ManyToManyField('tags')
    ...

class Tag(models.Model):
    name = models.CharField(max_length=140)
使用数组字段:

from django.contrib.postgres.fields import ArrayField

class Post(models.Model):
    tags = ArrayField(models.CharField(max_length=140))
    ...

假设我不关心在代码中支持其他数据库后端,那么推荐的解决方案是什么?

如果您希望监视类标记(例如:多少个标记,一个特定标记etd的数量),则选择第一个选项,因为您可以向模型添加更多字段,并将为应用程序增加丰富性

另一方面,如果只是为了显示或最小化处理而希望它是一个数组列表,请选择该选项

但如果你想节省时间,增加应用程序的丰富性,你可以使用这个

初始化就这么简单:

from django.db import models

from taggit.managers import TaggableManager

class Food(models.Model):
# ... fields here

    tags = TaggableManager()
并可按以下方式使用:

>>> apple = Food.objects.create(name="apple")
>>> apple.tags.add("red", "green", "delicious") 
>>> apple.tags.all()
[<Tag: red>, <Tag: green>, <Tag: delicious>]
苹果=食品。对象。创建(name=“苹果”) >>>苹果。标签。添加(“红色”、“绿色”、“美味”) >>>apple.tags.all() [, ]
如果使用数组字段

  • 数据库中每一行的大小都将有点大,因此Postgres将使用更多的数据

  • 每次获得该行时,除非您专门使用该字段或通过only、value或其他方式将其从查询中排除,否则每次迭代该行时,您都要支付加载所有这些值的费用。如果那是你需要的,那就这样吧

  • 基于该数组中的值进行过滤,虽然可能,但效果不会很好,Django ORM也不像M2M表那样明显

如果使用M2M字段

  • 您可以更轻松地筛选这些相关值 默认情况下,这些字段是延迟的,如果需要,可以使用prefetch_related,如果只想加载这些值的一个子集,则可以使用prefetch_related

  • 使用M2M时,由于密钥和额外的id字段,数据库中的总存储将略高

  • 在这种情况下,由于键的存在,连接的成本完全可以忽略不计

尽管如此,上述答案并不属于我。不久前,我在学习Django的时候偶然发现了这个难题。我在这里找到了这个问题的答案


希望你得到你想要的。

如果你不想重新发明轮子-@rayy,我的问题不是关于使用外部模块(我知道),更多关于实现选择,我想知道更多关于@e4c5的另一个可能的副本的字段类型的优缺点,尽管它是相关的,我不是问json字段。是的,我想我是无意中使用了错误的dup目标,但基本上你不应该使用arrayfield。虽然很简单,谢谢,但我的问题更多的是关于我的选择之间的区别,(为什么a比b好)taggit是个不错的选择,但我的问题并不完全是关于标记模块,你答案的第一部分是我一直在寻找的。哦,我明白了。我能回答你的问题吗?或者你还有其他问题吗?等待更详细的信息:-)