【问题标题】:Django can not makemigrations: can't create form field for followers yet. Because its related model 'self' has not been loaded yetDjango 不能进行迁移:还不能为关注者创建表单字段。因为它的相关模型'self'还没有被加载
【发布时间】:2019-06-02 10:07:53
【问题描述】:

这是模型。

class CustomUser(AbstractUser):
    followers = ArrayField(ArrayField(models.ForeignKey('self',
                                                        related_name = 'following_set',
                                                        on_delete = models.CASCADE ), size = 1))
    followings = ArrayField(ArrayField(models.ForeignKey('self',
                                                        related_name = 'follower_set',
                                                        on_delete = models.CASCADE ), size = 1))

【问题讨论】:

  • 不要使用ArrayField,您应该使用m2m 关系(或在两者之间添加一个表格)。事实上,数组无论如何都不是好习惯(这些不遵循 1NF)。

标签: django django-models


【解决方案1】:

正如ArrayField [Django-doc] 上的文档所说,您不能使用ForeignKey [Django-doc]

base_field

这是一个必需的参数。

指定数组的基础数据类型和行为。它 应该是Field 的子类的一个实例。例如,它可以 成为IntegerFieldCharField。大多数字段类型都是允许的, 处理关系数据的除外ForeignKeyOneToOneFieldManyToManyField)。

此外,ArrayFields 通常不是好习惯。许多数据库后端支持这些字段,而且它们很容易导致复杂的查询,并且通常没有有效的索引结构无论如何:如果你想找出常见的追随者是什么两个用户,这将导致一些复杂的逻辑。如果一定要在数组里面查询,那肯定不符合数据库first normal form (1NF) [wiki]的条件。虽然当然可以争论 1NF 是否总能提高数据库的整体质量,但我认为说ArrayFields 通常应该用作“最后的手段”,或者如果数组是“原子”对象。

最后通过使用两个数组,让两者保持同步将是一个技术挑战:如果a 不再跟随b,那么应该从bfollowers 中删除a , 但b 也应该从afollowings 中删除。这看起来很容易,但最终用例的数量会增加,最终会导致一些错误。

你可以构造一个ManyToMany model [Django-doc],比如:

class CustomUser(AbstractUser):
    followers = models.ManyToManyField(
        'self',
        symmetrical=False,
        related_name='following'
    )

这将在两者之间创建一个隐藏表。通过指定symmetrical=False [Django-doc],这意味着如果用户u1 关注用户u2,那么u2 本身 关注u1

如果您想在“关注”关系中添加额外数据,例如用户开始关注另一个用户时的时间戳,您可以创建一个类似 Follow 的模型,并将其指定为 @ 的 through= 模型987654355@.

【讨论】:

  • “可以争论 1NF 是否总是能提高数据库的整体质量”您是在谈论报告表中的非规范化吗?
  • @thebjorn:在某些情况下,比如负载巨大的数据库,不遵循 1NF 可能是有益的(比如分片)。因此,与大多数设计原则一样,可能存在某些情况。我只是说对于非边缘情况,通常最好遵循正常形式。
  • 好的,我明白了(我只是从未听说过低于 4 或 5 的范式在关系数据方面存在争议——那么我再次认为追随者与关系数据一样多层次......)
猜你喜欢
  • 1970-01-01
  • 2022-01-10
  • 2013-06-13
  • 2017-09-15
  • 1970-01-01
  • 2023-03-17
  • 2020-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多