“为'XXX'的定义添加related_name参数的自动解决方案。”?

时间:2011-03-15 17:13:59

标签: python database django django-models

我将Django插入现有系统。我已经获得了遗留架构,我必须使用它。

我已经使用inspectdb生成了模型,但我得到了数百个:

ABC>DEF: Accessor for field 'HIJ' clashes with related field 'KLM'. Add a related_name argument to the definition for 'HIJ'.

如果它只是一个小数字,我就不会有问题。但事实并非如此。

是否有任何自动方法可以通过添加唯一的related_name来解决此问题?

编辑:为了澄清,我正在寻找问题的自动解决方案,而不是涉及手动编辑每个字段的问题。

4 个答案:

答案 0 :(得分:2)

如果您不需要相关名称,可以set it to "+"

如果您不想完全禁用它们或者不能在django版本中使用“+”(我记不清它何时添加),您可以使用以下内容:

_no_related_name_counter = 0
def no_related_name():
    _no_related_name_counter += 1
    return "_norn_%%(class)s_%i" % _no_related_name_counter

ForeignKey(..., related_name=no_related_name())

但是,如果您使用正则表达式搜索和替换插入相关名称,您也可以将它们设置为可读的内容,例如将(\s*(\w+)\s*=\s*models\.ForeignKey\(.*)\)(\s*)$替换为$1, related_name="%(class)s_$2_reverse")$3

答案 1 :(得分:1)

您应该通过指定related_name检查外键关系,如下所示:

user = models.ForeignKey(User, related_name='user')
admin = models.ForeignKey(User, related_name='user1') #you need to use a different related_name here

希望它有所帮助。

答案 2 :(得分:0)

有时我会遇到这种情况。修改inspectdb在某些情况下对我有用,但我不能保证在每种情况下都适用。这是我所做的:

    #Original inspectdb
    121                         if rel_to in known_models:
    122                             field_type = 'ForeignKey(%s' % rel_to
    123                         else:
    124                             field_type = "ForeignKey('%s'" % rel_to

    #Modified inspectdb
    121                         if rel_to in known_models:
    122                             field_type = 'ForeignKey(%s' % rel_to
    123                         else:
    124                             field_type = "ForeignKey('%s'" % rel_to
    125                         extra_params['related_name'] = '%s_%s' % (table2model(table_name),column_to_field_name[column_name])

这将自动向每个生成的模型添加一个related_name参数,该模型不太可能与其他模型碰撞。再次,这取决于情况,但是这种单行修改节省了我很多工作。

答案 3 :(得分:0)

如果你想处理大型遗留数据库并且不想使用'+',你可以运行一个简单的脚本来修改生成的models.py文件,如下所示:

import fileinput
textToSearch = "models.DO_NOTHING"

_no_related_name_counter = 1000

with fileinput.FileInput('models.py', inplace=True, backup='.bak') as file:
    for line in file:
        _no_related_name_counter += 1
        textToReplace = 'models.DO_NOTHING, related_name="%(class)s_{}"'.format(_no_related_name_counter)
        print(line.replace(textToSearch, textToReplace), end='')