[Django]-Automatic solution for "Add a related_name argument to the definition for 'XXX'."?

2👍

If you don’t need the related name, you can set it to “+”.

If you don’t want to disable them completely or cannot use “+” in your django version (I can’t remember when it was added), you may use something like the following:

_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())

But if you insert related names with a regexp search and replace, you may as well set them to something readable, e.g. replace (\s*(\w+)\s*=\s*models\.ForeignKey\(.*)\)(\s*)$ with $1, related_name="%(class)s_$2_reverse")$3

4👍

Occasionally I find myself in this situation. Modifying inspectdb has worked for me in several instances but I can’t promise it’ll be appropriate in every situation. Here’s what I’ve done:

    #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])

This will automatically add a related_name argument to every generated model that isn’t likely to collide with any others. Again, it depends on the situation, but this single line modification has saved me tons of work.

1👍

You should check the foreign key relationships by specifying the related_name, like this:

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

Hope it helps.

👤zs2020

0👍

If you want to deal with large legacy database and dont want to use ‘+’ you can run a simple script to modify the generated models.py file as follows:

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='')

Leave a comment