yamachan
yamachan

Reputation: 1079

Django OneToOneField and ForeignKeyField add "_id" suffix to the field

When I checked group_cover table which is created by Django, there were group_id_id field and group_cover field. I'd like to change group_id_id to group_id.

models.py

class Group(models.Model):

    group_id = models.AutoField(primary_key=True)
    group_name = models.CharField(max_length=50, unique=False, blank=False)


class Group_Cover(models.Model):

    group_id = models.OneToOneField(Group, primary_key=True)  # this create group_id_id
    group_cover = models.ImageField(upload_to="/image/group/") 


class Group_Member(models.Model):

    user_id = models.ForeignKey(User2)  # this create user_id_id
    group_id = models.ForeignKey(Group)  # this create group_id_id

Yeah, if I write,

group = models.OneToOneField(Group, primary_key=True)

It might work, but I may not need "_id" suffix on some field.

I read this document, but owing to my poor English, I couldn't understand the way. Would you please teach me how to change?

Upvotes: 1

Views: 2756

Answers (3)

Lucas03
Lucas03

Reputation: 2347

You should not worry about _id that is being added in database table. You should not deal with database if you are using ORM in Django. Also, you do not need to specify id unless its special type - group of attributes.
I would do it like this (I believe you do not need that many classes):

class Group(models.Model):
    name = models.CharField(max_length=50, unique=False, blank=False)
    cover = models.ImageField(upload_to="/image/group/") 
    users = models.ManyToManyField(User2)

Then you should access attributes with object notation. If you want id, use group.id, if you want to filter object, use Group.objects.filter(id__gt=10) or Group.objects.get(id=1) etc. My model should be doing exactly what you want to achieve.

Upvotes: 2

Lee
Lee

Reputation: 5936

Django adds an _id postix to primary keys that are generated automatically. You generally don't need to worry about them unless using a legacy data base.

Solution 2 would be the one i would recommend for a new project. Solution 1 for legacy databases.

Solution 1

To modify your existing code, use the following db_column attribute as it allows you to name the field in the database.:

group = models.AutoField(primary_key=True, db_column='group_id')

Documentation

Solution 2

To get the same results in a more "Django" way let Django generate the Primary keys automatically then reference the model in the OneToOne and Foreign key fields as shown below.

class Group(models.Model):
    group_name = models.CharField(max_length=50, unique=False, blank=False)

class Group_Cover(models.Model):
    group = models.OneToOneField(Group)
    group_cover = models.ImageField(upload_to="/image/group/") 

class Group_Member(models.Model):
    user = models.ForeignKey(User2)
    group = models.ForeignKey(Group)

Upvotes: 4

Sayse
Sayse

Reputation: 43300

Your assumption is correct, you need to rename your fields to not include the _id (i.e group instead of group_id). This will fix your "issue" but more than anything it more accurately represents the relationship/field. You have relationships to a model, not a reference to the id.

_id is an automatic reference provided by django to make it easier to just retrieve the _id from a model.

From the documentation

Behind the scenes, Django appends "_id" to the field name to create its database column name. In the above example, the database table for the Car model will have a manufacturer_id column. (You can change this explicitly by specifying db_column) However, your code should never have to deal with the database column name, unless you write custom SQL. You’ll always deal with the field names of your model object.

Upvotes: 3

Related Questions