如何修复“ Follow.s_id”不是“用户”的外键。

时间:2019-10-25 22:04:04

标签: django-models

我是Django框架的新手,我正在尝试构建以下系统,该系统包含一个跟随多只股票并且多只股票跟随其后的用户,我试图使用中间类来创建组合键,但是我遇到这个错误。



class Stock(models.Model):
    symbol = models.CharField(max_length=12, primary_key=True,default="")
    name = models.CharField(max_length=64)
    top_rank = models.IntegerField(null=True)
    price = models.FloatField()
    change = models.FloatField(null=True)
    change_percent = models.FloatField()
    market_cap = models.FloatField(null=True)
    primary_exchange = models.CharField(null=True, max_length=32) # NASDAQ
    followers = models.ManyToManyField('myapp.Users',through='Follow',through_fields=('u_id','s_id'))


class Users(models.Model):
    user_id = models.IntegerField(primary_key=True,default="")
    name = models.CharField(max_length=12)

class Follow(models.Model):
    u_id=models.ForeignKey('Users',on_delete=models.CASCADE)
    s_id=models.ForeignKey('Stock',on_delete=models.CASCADE)



myapp.Stock.followers: (fields.E339) 'Follow.s_id' is not a foreign key to 'Users'.
        HINT: Did you mean one of the following foreign keys to 'Users': u_id?
myapp.Stock.followers: (fields.E339) 'Follow.u_id' is not a foreign key to 'Stock'.
        HINT: Did you mean one of the following foreign keys to 'Stock': s_id?

1 个答案:

答案 0 :(得分:0)

through_fields [Django-doc]的顺序不正确。如文档中所指定:

  

through_fields接受2元组('field1', 'field2'),其中field1ManyToManyField上定义的模型的外键名称(...),以及field2 目标模型(...)的外键名称。

因此,这意味着through_fields的第一项应为's_id',因为它引用了Stock模型,定义了ManyToManyField的模型以及第二项应该是'u_id'

class Stock(models.Model):
    # …
    followers = models.ManyToManyField(
        'myapp.Users',
        through='Follow',
        through_fields=('s_id','u_id')
    )

话虽如此,您这里不需要定义through_fields,因为您的Follow模型包含恰好两个ForeignKey,它们指向不同的楷模。实际上,您也不需要定义through=...模型,因为它不包含任何额外的字段。

请注意,通常情况下,ForeignKey并不包含_id后缀,因为Django会自动添加带有_id后缀的额外字段,其中包含主要字段参考值的键。

因此,将模型定义为:

class Stock(models.Model):
    symbol = models.CharField(max_length=12, primary_key=True)
    name = models.CharField(max_length=64)
    top_rank = models.IntegerField(null=True)
    price = models.FloatField()
    change = models.FloatField(null=True)
    change_percent = models.FloatField()
    market_cap = models.FloatField(null=True)
    primary_exchange = models.CharField(null=True, max_length=32) # NASDAQ
    followers = models.ManyToManyField('myapp.User')


class User(models.Model):
    user_id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=12)

请注意,模型通常具有单数名称,因此User而不是 Users