django的数据库模型中的域多次引用同一个外键(表)

执行python manage makemigrations OnlineUpgrade时,报如下错误:

<span style="color:#ff6666;">D:\KLServer\pycode\KLServer>python manage.py makemigrations OnlineUpgrade
SystemCheckError: System check identified some issues:


ERRORS:
OnlineUpgrade.SoftwareUpgradeRecord.high_version: (fields.E304) Reverse accessor for 'SoftwareUpgradeRecord.high_version' clashes with reverse accessor for 'SoftwareVersionDiff.high_version'.
        HINT: Add or change a related_name argument to the definition for 'SoftwareUpgradeRecord.high_version' or 'SoftwareVersionDiff.high_version'.
OnlineUpgrade.SoftwareUpgradeRecord.high_version: (fields.E304) Reverse accessor for 'SoftwareUpgradeRecord.high_version' clashes with reverse accessor for 'SubSoftwareKitVersionDiff.high_version'.
        HINT: Add or change a related_name argument to the definition for 'SoftwareUpgradeRecord.high_version' or 'SubSoftwareKitVersionDiff.high_version'.
OnlineUpgrade.SoftwareUpgradeRecord.high_version: (fields.E305) Reverse query name for 'SoftwareUpgradeRecord.high_version' clashes with reverse query name for 'SoftwareVersionDiff.high_version'.
        HINT: Add or change a related_name argument to the definition for 'SoftwareUpgradeRecord.high_version' or 'SoftwareVersionDiff.high_version'.
OnlineUpgrade.SoftwareUpgradeRecord.high_version: (fields.E305) Reverse query name for 'SoftwareUpgradeRecord.high_version' clashes with reverse query name for 'SubSoftwareKitVersionDiff.high_version'.
        HINT: Add or change a related_name argument to the definition for 'SoftwareUpgradeRecord.high_version' or 'SubSoftwareKitVersionDiff.high_version'.
OnlineUpgrade.SoftwareUpgradeRecord.low_version: (fields.E304) Reverse accessor for 'SoftwareUpgradeRecord.low_version' clashes with reverse accessor for 'SoftwareVersionDiff.low_version'.
        HINT: Add or change a related_name argument to the definition for 'SoftwareUpgradeRecord.low_version' or 'SoftwareVersionDiff.low_version'.
OnlineUpgrade.SoftwareUpgradeRecord.low_version: (fields.E305) Reverse query name for 'SoftwareUpgradeRecord.low_version' clashes with reverse query name for 'SoftwareVersionDiff.low_version'.
        HINT: Add or change a related_name argument to the definition for 'SoftwareUpgradeRecord.low_version' or 'SoftwareVersionDiff.low_version'.
OnlineUpgrade.SoftwareVersionDiff.high_version: (fields.E304) Reverse accessor for 'SoftwareVersionDiff.high_version' clashes with reverse accessor for 'SoftwareUpgradeRecord.high_version'.
        HINT: Add or change a related_name argument to the definition for 'SoftwareVersionDiff.high_version' or 'SoftwareUpgradeRecord.high_version'.
OnlineUpgrade.SoftwareVersionDiff.high_version: (fields.E304) Reverse accessor for 'SoftwareVersionDiff.high_version' clashes with reverse accessor for 'SubSoftwareKitVersionDiff.high_version'.
        HINT: Add or change a related_name argument to the definition for 'SoftwareVersionDiff.high_version' or 'SubSoftwareKitVersionDiff.high_version'.
OnlineUpgrade.SoftwareVersionDiff.high_version: (fields.E305) Reverse query name for 'SoftwareVersionDiff.high_version' clashes with reverse query name for 'SoftwareUpgradeRecord.high_version'.
        HINT: Add or change a related_name argument to the definition for 'SoftwareVersionDiff.high_version' or 'SoftwareUpgradeRecord.high_version'.
OnlineUpgrade.SoftwareVersionDiff.high_version: (fields.E305) Reverse query name for 'SoftwareVersionDiff.high_version' clashes with reverse query name for 'SubSoftwareKitVersionDiff.high_version'.
        HINT: Add or change a related_name argument to the definition for 'SoftwareVersionDiff.high_version' or 'SubSoftwareKitVersionDiff.high_version'.
OnlineUpgrade.SoftwareVersionDiff.low_version: (fields.E304) Reverse accessor for 'SoftwareVersionDiff.low_version' clashes with reverse accessor for 'SoftwareUpgradeRecord.low_version'.
        HINT: Add or change a related_name argument to the definition for 'SoftwareVersionDiff.low_version' or 'SoftwareUpgradeRecord.low_version'.
OnlineUpgrade.SoftwareVersionDiff.low_version: (fields.E305) Reverse query name for 'SoftwareVersionDiff.low_version' clashes with reverse query name for 'SoftwareUpgradeRecord.low_version'.
        HINT: Add or change a related_name argument to the definition for 'SoftwareVersionDiff.low_version' or 'SoftwareUpgradeRecord.low_version'.
OnlineUpgrade.SubSoftwareKitVersionDiff.high_version: (fields.E304) Reverse accessor for 'SubSoftwareKitVersionDiff.high_version' clashes with reverse accessor for 'SoftwareUpgradeRecord.high_version'.
        HINT: Add or change a related_name argument to the definition for 'SubSoftwareKitVersionDiff.high_version' or 'SoftwareUpgradeRecord.high_version'.
OnlineUpgrade.SubSoftwareKitVersionDiff.high_version: (fields.E304) Reverse accessor for 'SubSoftwareKitVersionDiff.high_version' clashes with reverse accessor for 'SoftwareVersionDiff.high_version'.
        HINT: Add or change a related_name argument to the definition for 'SubSoftwareKitVersionDiff.high_version' or 'SoftwareVersionDiff.high_version'.
OnlineUpgrade.SubSoftwareKitVersionDiff.high_version: (fields.E305) Reverse query name for 'SubSoftwareKitVersionDiff.high_version' clashes with reverse query name for 'SoftwareUpgradeRecord.high_version'.
        HINT: Add or change a related_name argument to the definition for 'SubSoftwareKitVersionDiff.high_version' or 'SoftwareUpgradeRecord.high_version'.
OnlineUpgrade.SubSoftwareKitVersionDiff.high_version: (fields.E305) Reverse query name for 'SubSoftwareKitVersionDiff.high_version' clashes with reverse query name for 'SoftwareVersionDiff.high_version'.
        HINT: Add or change a related_name argument to the definition for 'SubSoftwareKitVersionDiff.high_version' or 'SoftwareVersionDiff.high_version'.</span>



原来的模型代码:

@python_2_unicode_compatible
class SoftwareVersionDiff(models.Model):
    '''
    软件版本差分
    '''

    # 软件
    software = models.ForeignKey(to=Software, verbose_name='软件')

    # 低版本
    low_version = models.ForeignKey(to=Version,
                                    related_name='low_version', verbose_name='低版本')

    # 高版本
    high_version = models.ForeignKey(to=Version,
                                     related_name='high_version', verbose_name='高版本')


@python_2_unicode_compatible
class SubSoftwareKitVersionDiff(models.Model):
    '''
    软件子集版本差分
    '''

    # 软件子集
    subsoftwarekit = models.ForeignKey(to=SubSoftwareKit, verbose_name='软件子集')


    # 低版本
    low_version = models.ForeignKey(to=Version,
                                    related_name='low_versin_subsoftware', verbose_name='低版本')

    # 高版本
    high_version = models.ForeignKey(to=Version,
                                     related_name='high_version',verbose_name='高版本')


@python_2_unicode_compatible
class SoftwareUpgradeRecord(models.Model):
    '''
    软件更新记录,记录更新过程
    这里特别需要注意的是,一次更新请求中可能会有许多的软件需要更新,这个时候一次请求,可能会
    触发多次更新记录,因为每个软件更新的(低版本->高版本)是不一样的。
    '''
    # 更新的所有软件
    softwares = models.CharField(verbose_name='软件', max_length=2048, null=False)

    # 低版本
    low_version = models.ForeignKey(to=Version,
                                    related_name='low_version', verbose_name='低版本')

    # 高版本
    high_version = models.ForeignKey(to=Version,
                                     related_name='high_version', verbose_name='高版本')

原因: 因为在一个表中多次引用某个外键表,而且没有指定唯一的releated_name,而导致的。

解决方案:将同一个表中的releated_name,全部修改,指定不一样的releated_name

修改后的代码

@python_2_unicode_compatible
class SoftwareVersionDiff(models.Model):
    '''
    软件版本差分
    '''

    # 软件
    software = models.ForeignKey(to=Software, verbose_name='软件')

    # 低版本
    low_version = models.ForeignKey(to=Version,
                                    related_name='low_version_software_version_diff', verbose_name='低版本')

    # 高版本
    high_version = models.ForeignKey(to=Version,
                                     related_name='high_version_software_version_diff', verbose_name='高版本')


@python_2_unicode_compatible
class SubSoftwareKitVersionDiff(models.Model):
    '''
    软件子集版本差分
    '''

    # 软件子集
    subsoftwarekit = models.ForeignKey(to=SubSoftwareKit, verbose_name='软件子集')


    # 低版本
    low_version = models.ForeignKey(to=Version,
                                    related_name='low_versin_subsoftware_version_diff', verbose_name='低版本')

    # 高版本
    high_version = models.ForeignKey(to=Version,
                                     related_name='high_version_subsoftware_version_diff',verbose_name='高版本')


@python_2_unicode_compatible
class SoftwareUpgradeRecord(models.Model):
    '''
    软件更新记录,记录更新过程
    这里特别需要注意的是,一次更新请求中可能会有许多的软件需要更新,这个时候一次请求,可能会
    触发多次更新记录,因为每个软件更新的(低版本->高版本)是不一样的。
    '''
    # 更新的所有软件
    softwares = models.CharField(verbose_name='软件', max_length=2048, null=False)

    # 低版本
    low_version = models.ForeignKey(to=Version,
                                    related_name='low_version_software_upgrade_record', verbose_name='低版本')

    # 高版本
    high_version = models.ForeignKey(to=Version,
                                     related_name='high_version_software_upgrade_record', verbose_name='高版本')





### 回答1: 在Django,可以使用select_related()方法一次性查询多个记录对应的外键数据。这样可以避免N+1查询问题,提高查询效率。 例如,如果有一个为Book,外键为Author,可以这样查询: books = Book.objects.all().select_related('author') 这样books变量的每一个Book对象都会有一个author属性,通过这个属性可以访问对应的Author对象。 ### 回答2: 在Django,如果要同时查询主对应的外键数据,可以使用select_related方法。select_related方法可以在一次数据库查询同时获取主外键数据。 例如,假设有一个Post和外键Comment,每个Post都有多个对应的Comment,想要同时获取每个Post对应的所有Comment。 可以通过如下代码实现: posts = Post.objects.select_related('comment_set') for post in posts: print(f"Post标题:{post.title}") for comment in post.comment_set.all(): print(f"评论:{comment.content}") 在上述代码,使用select_related('comment_set')来告诉Django在查询Post时同时获取其关联的Comment数据。然后通过post.comment_set.all()来获取每个Post对应的所有Comment。 使用select_related方法可以减少数据库查询的次数,提高查询效率。但需要注意,如果外键关联的数据较多,使用select_related可能会导致查询语句过于庞大,建议适量使用。 ### 回答3: 在Django,可以使用多种方式同时查询主对应的外键数据。 一种常见的方法是使用`select_related()`函数,它可以在查询主数据的同时同时查询外键数据。例如,假设有一个`User`和外键`Profile`,可以通过以下代码同时查询两个的数据: ``` users = User.objects.select_related('profile').all() for user in users: print(user.profile) ``` 这样就可以通过`user.profile`属性获取到每个用户对应的外键数据。 另外一种方法是通过反向查询外键数据。在模型,可以设置`related_name`属性来定义反向查询的名称。例如,如果在主设置了`profile = models.ForeignKey(Profile, related_name='users')`,则可以通过以下代码同时查询主外键的数据: ``` profiles = Profile.objects.all() for profile in profiles: print(profile.users.all()) ``` 这样就可以通过`profile.users.all()`获取到每个外键数据对应的主数据。 需要注意的是,以上方法都会在查询数据时产生额外的SQL查询,因此在进行大量数据查询时可能会影响性能。如果需要在一个查询获取所有的主外键数据,可以考虑使用`prefetch_related()`函数来优化查询性能。 总之,以上是在Django同时查询主对应的外键数据的几种常见方法。根据实际需求和数据量大小,可以选择合适的方法来进行查询。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值