14

This time I think it's not me being stupid but an actual conflict. I have the below code (simplified):

from django.db import models

class Alpha(models.Model):
    relation = models.ForeignKey('Delta', related_name = 'reverse_relation', blank = True, null = True)

    class Meta:
        abstract = True

class Beta(Alpha):
    pass

class Gamma(Alpha):
    pass

class Delta(models.Model):
    pass

The problem is that Delta.reverse_relation could refer to an instance of Beta or an instance of Gamma. I would somehow have to provide multiple related_name values (or one that depends on the class name).I think the problem is clear but to be complete, the error (when running syncdb): app.beta: Accessor for field 'relation' clashes with related field 'Delta.reverse_relation'. Add a related_name argument to the definition for 'relation'.
app.beta: Reverse query name for field 'relation' clashes with related field 'Delta.reverse_relation'. Add a related_name argument to the definition for 'relation'.
app.gamma: Accessor for field 'relation' clashes with related field 'Delta.reverse_relation'. Add a related_name argument to the definition for 'relation'.
app.gamma: Reverse query name for field 'relation' clashes with related field 'Delta.reverse_relation'. Add a related_name argument to the definition for 'relation'.

Is it possible at all to place the ForeignKey in the parent Alpha, or is the only way to cut-paste this code to Beta and Gamma? I prefer not to do that because it kind of defeats the point of inheritance if I can't define in the parent half the fields that all children share.

Any help is much apprectiated!

(If anyone can comment with why the error messages aren't in a code box I'll fix that.)

Mark
  • 18,730
  • 7
  • 107
  • 130

1 Answers1

22

I think that you will find the following advice in the Django documentation helpful and relevant: https://docs.djangoproject.com/en/1.7/topics/db/models/#be-careful-with-related-name

Essentially change the declaration of the relation field to:

relation = models.ForeignKey('Delta', related_name="%(app_label)s_%(class)s")

Best of luck...

ruddra
  • 50,746
  • 7
  • 78
  • 101
banerjs
  • 538
  • 6
  • 14
  • Thanks for the reply, hope it helps more people to find this solution! – Mark Sep 16 '11 at 18:36
  • What if I have two foreign keys with same app labels? I m not able to find answer. – Manoj Jadhav Jul 12 '17 at 05:16
  • The `related_name` is simply a templated string with keywords `app_label` and `class`. If needed, you could specify the `related_name` for the first foreign_key as `"%(app_label)s_%(class)s_fk1_set"` and for the second as `"%(app_label)s_%(class)s_fk2_set"` (or any other string of your choice) – banerjs Jul 13 '17 at 18:38