djangodjango-modelsdjango-1.9django-1.6

related_name changed after 1.6


I'm upgrading from 1.6 to 1.9. My project includes code derived from this sample AuditTrail: https://code.djangoproject.com/wiki/AuditTrail

Essentially, this AuditTrail allows to create an Audit model on-the-fly to record any changes to an audit table.

Part of the code needs to make sure to avoid clashes between related_name. This is done as follows, and works fine as of 1.6.

if isinstance(field, models.ForeignKey):
  rel = copy.copy(field.rel)
  rel.related_name = '_audit_' + field.related_query_name()
  attrs[field.name].remote_field = rel

For some reason, after upgrading, django fails with SystemCheckError on all of these, with a traceback looking like:

SystemCheckError: System check identified some issues:

ERRORS:
email_reporting.ReportAudit.team: (fields.E304) Reverse accessor for 'ReportAudit.team' clashes with reverse accessor for 'Report.team'.
        HINT: Add or change a related_name argument to the definition for 'ReportAudit.team' or 'Report.team'.
email_reporting.ReportAudit.team: (fields.E305) Reverse query name for 'ReportAudit.team' clashes with reverse query name for 'Report.team'.
        HINT: Add or change a related_name argument to the definition for 'ReportAudit.team' or 'Report.team'.

Any ideas how to fix it? I can't find any changes to related_name that may be the culprit.

This only happens if I start django with ./manage.py shell_plus, but things seem to boot up properly if started with ./manage.py shell.


Solution

  • The solution was to directly modify rel instead of remote_field

    if isinstance(field, models.ForeignKey):
        rel = copy.copy(field.rel)
        if rel.related_name:
            rel.related_name = '_audit_' + rel.related_name
        elif rel:
            rel.related_name = '_audit_' + rel.get_accessor_name()
        attrs[field.name].rel.related_name=rel.related_name