AnotherHowie
AnotherHowie

Reputation: 822

Django migrations - how to make it forget?

I've been sketching out a new Django app with the runserver dev server running in a background window to tracking network wiring, and briefly had this in my model:

class Interface(models.Model):
    name = models.CharField(max_length=200)
    # (blah)

class Connection(models.Model):
    interface_from = models.ForeignKey(Interface, related_name="connections")
    interface_to = models.ForeignKey(Interface, related_name="connections")
    source = models.CharField(max_length=32)

Before I realised I couldn't have the same related_name for two fields. I guess I will need to write something special to find all connections related to an interface, since they might be the 'to' or 'from' end of the connection (be interested in any insight on a nicer way to do that - like a "Set" field)

At this point, I hadn't done a makemigrations, but on stopping the server, and making my migrations, I get:

ERRORS:
autodoc.Connection.interface_from: (fields.E304) Reverse accessor for 'Connection.interface_from' clashes with reverse accessor for 'Connection.interface_to'.
HINT: Add or change a related_name argument to the definition for 'Connection.interface_from' or 'Connection.interface_to'.

Even though there isn't a clash anymore. I don't see a migrations directory anywhere - this was the initial pass at the models - so where is the memory of this error coming from after a restart of the dev server?

Edit: To make it clearer, my Connection model now looks like:

class Connection(models.Model):
    interface_from = models.ForeignKey(Interface)
    interface_to = models.ForeignKey(Interface)
    source = models.CharField(max_length=32)

Upvotes: 0

Views: 119

Answers (2)

Josh Kelley
Josh Kelley

Reputation: 58422

In your first example:

class Connection(models.Model):
    interface_from = models.ForeignKey(Interface, related_name="connections")
    interface_to = models.ForeignKey(Interface, related_name="connections")

You're telling Django to create two different connections attributes on Interface for the backwards relationships back to Connection, which obviously doesn't work.

In your second example:

class Connection(models.Model):
    interface_from = models.ForeignKey(Interface)
    interface_to = models.ForeignKey(Interface)

You're telling Django to use its default connections_set name for two different attributes for the backwards relationships back to Connection, which also doesn't work.

The fix is to use related_name='+' (as @Ivan said) to disable the backwards relationships completely or two explicitly provide two different related_name attributes so that the backwards relationship attributes' names don't clash.

Upvotes: 1

Ivan
Ivan

Reputation: 6013

In case you don't need a backwards relation add related_name='+' to your field definition. From the doc:

user = models.ForeignKey(User, related_name='+')

Upvotes: 2

Related Questions