Django Models relation with primary key add extra "_id" to the column

These are my two models, when I try to open City page on Django I get an error: "column city.country_id_id does not exist". I don't know why python adds extra _id there.

class Country(models.Model):
    country_id = models.CharField(primary_key=True,max_length=3)
    country_name = models.CharField(max_length=30, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'country'

class City(models.Model):
    city_id=models.CharField(primary_key=True,max_length=3)
    city_name=models.CharField(max_length=30, blank=True, null=True)
    country_id = models.ForeignKey(Country, on_delete=models.CASCADE)

    class Meta:
        managed = False
        db_table = 'city'

Image

Upvotes: 1

Views: 1937

Answers (2)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476574

Because if you construct a foreign key, Django will construct a "twin field" that stores the primary key of the object. The foreign key itself is thus more a "proxy" field that fetches the object.

Therefore you normally do not add an _id suffix to the ForeignKey:

class City(models.Model):
    city_id = models.CharField(primary_key=True,max_length=3)
    city_name = models.CharField(max_length=30, blank=True, null=True)
    country = models.ForeignKey(Country, on_delete=models.CASCADE)

    class Meta:
        managed = False
        db_table = 'city'

It however might be better for unmanaged tables, to specify a db_column=… parameter [Djang-doc] in the ForeignKey:

class City(models.Model):
    city_id = models.CharField(primary_key=True,max_length=3)
    city_name = models.CharField(max_length=30, blank=True, null=True)
    country = models.ForeignKey(Country, db_column='country_id', on_delete=models.CASCADE)

    class Meta:
        managed = False
        db_table = 'city'

With this parameter you make it explicit how the column is named at the database side.

Upvotes: 2

LetItBeAndre
LetItBeAndre

Reputation: 151

this is due to Django's behind the scenes magic. The fields documentation is very clear about that and I highly recommend you read the Foreign Key section in the link below: https://docs.djangoproject.com/en/3.0/ref/models/fields/#django.db.models.ForeignKey

Basically, when you want to access the Country reference in the if a City instance, you would do it like this: city.country_id

I also recommend another naming convention for your Foreign Key fields. Instead of <modelname>_id = models.ForeignKey... just call it <modelname> = models.ForeignKey...

Hope this helps, happy coding

Upvotes: 1

Related Questions