2019-08-23
Error when using two matching foreignKeys in django
stackoverflow
Question

I'm trying to create an inventory management system in django for keeping track of equipment used in the live events area, and I have been hitting this error when I attempt to makemigrations.

I have looked hard for typos (as all the solutions I have found have been typo related) and wasn't able to find anything. I'm assuming that this has something to do with using the same foreign key twice.

from django.db import models
from .tools import barutils
from .tools import types as choices


class venue(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=100, blank=False)
    desc = models.CharField(max_length=512, blank=True, null=True)


class location(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=100, blank=False)
    venue = models.ForeignKey(venue, on_delete=models.CASCADE, null=True)


class type(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=124, blank=False)


class item(models.Model):
    id = models.BigIntegerField(primary_key=True)
    type = models.ForeignKey(type, on_delete=models.CASCADE, null=False)
    location = models.ForeignKey(location, on_delete=models.SET_NULL, null=True, related_name="current_location")
    home = models.ForeignKey(location, on_delete=models.SET_NULL, null=True, related_name="home_location")
    out = models.BooleanField(null=True)

The code above produces this error.

Traceback (most recent call last):
  File "F:\Documents\Home\Programming\Active\Vento\venv\lib\site-packages\django\db\models\fields\related.py", line 786, in __init__
    to._meta.model_name
AttributeError: 'ForeignKey' object has no attribute '_meta'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "F:\Documents\Home\Programming\Active\Vento\manage.py", line 21, in <module>
    main()
  File "F:\Documents\Home\Programming\Active\Vento\manage.py", line 17, in main
    execute_from_command_line(sys.argv)
  File "F:\Documents\Home\Programming\Active\Vento\venv\lib\site-packages\django\core\management\__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "F:\Documents\Home\Programming\Active\Vento\venv\lib\site-packages\django\core\management\__init__.py", line 357, in execute
    django.setup()
  File "F:\Documents\Home\Programming\Active\Vento\venv\lib\site-packages\django\__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "F:\Documents\Home\Programming\Active\Vento\venv\lib\site-packages\django\apps\registry.py", line 114, in populate
    app_config.import_models()
  File "F:\Documents\Home\Programming\Active\Vento\venv\lib\site-packages\django\apps\config.py", line 211, in import_models
    self.models_module = import_module(models_module_name)
  File "C:\Users\tyler\AppData\Local\Programs\Python\Python37-32\lib\importlib\__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "F:\Documents\Home\Programming\Active\Vento\dashboard\models.py", line 23, in <module>
    class item(models.Model):
  File "F:\Documents\Home\Programming\Active\Vento\dashboard\models.py", line 27, in item
    home = models.ForeignKey(location, on_delete=models.SET_NULL, null=True, related_name="home_location")
  File "F:\Documents\Home\Programming\Active\Vento\venv\lib\site-packages\django\db\models\fields\related.py", line 792, in __init__
    RECURSIVE_RELATIONSHIP_CONSTANT,
AssertionError: ForeignKey(<django.db.models.fields.related.ForeignKey>) is invalid. First parameter to ForeignKey must be either a model, a model name, or the string 'self'
Answer
1

Lets explain it using location and 'venue' classes:

class venue(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=100, blank=False)
    desc = models.CharField(max_length=512, blank=True, null=True)

class location(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=100, blank=False)
    venue = models.ForeignKey(venue, on_delete=models.CASCADE, null=True)

You want to reference the venue to its class but it has the same name as the field (venue) that you have defined for location. so it will consider that instead of the model class . So that is not a django model and will fail.

Try to change the name of the classes to their CamelCase type and set their fields which are foreign keys using underline.

So it would be like this:

class Venue(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=100, blank=False)
    desc = models.CharField(max_length=512, blank=True, null=True)


class Location(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=100, blank=False)
    venue = models.ForeignKey(Venue, on_delete=models.CASCADE, null=True)

class Type(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=124, blank=False)


class Item(models.Model):
    id = models.BigIntegerField(primary_key=True)
    type = models.ForeignKey(Type, on_delete=models.CASCADE, null=False)
    location = models.ForeignKey(Location, on_delete=models.SET_NULL, null=True, related_name="current_location")
    home = models.ForeignKey(Location, on_delete=models.SET_NULL, null=True, related_name="home_location")
    out = models.BooleanField(null=True)
Error when using two matching foreignKeys in django
See more ...