Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using '_id' in Django

I am a bit confused how Django handles '_id' property when we use ORM with some models that use foreign key. For example:

class CartItem(models.Model):
    user = models.ForeignKey('accounts.CustomUser', related_name='carts', on_delete=models.CASCADE, verbose_name='User')
    product = models.ForeignKey('pizza.Product', related_name='carts', on_delete=models.CASCADE, verbose_name=_('Product'))
    quantity = models.SmallIntegerField(verbose_name=_('Quantity'))

And when I use ORM with 'filter' I can easily use something like:

CartItem.objects.filter(user=1, product=1, quantity=1)

And Django kind of 'see' that I refer to 'id', but when I use exacly the same line of code, but with 'create' instead of 'filter':

CartItem.objects.create(user=1, product=1, quantity=1)

Then it throws an error saying:

Cannot assign "1": "CartItem.user" must be a "CustomUser" instance.

And to create it I need to use:

CartItem.objects.create(user_id=1, product_id=1, quantity=1)

Why is that? Is there some rule here that I don't understand?

like image 904
Sygol Avatar asked Oct 26 '19 17:10

Sygol


People also ask

Do Django models have ID?

By default, Django adds an id field to each model, which is used as the primary key for that model. You can create your own primary key field by adding the keyword arg primary_key=True to a field.

What is __ str __ in Django?

str function in a django model returns a string that is exactly rendered as the display name of instances for that model.

How do I create a one to many relationship in Django?

To handle One-To-Many relationships in Django you need to use ForeignKey . The current structure in your example allows each Dude to have one number, and each number to belong to multiple Dudes (same with Business).


1 Answers

This is the database representation of the ForeignKey [Django-doc]. A reference to model object is represented as:

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.

So you could say that Django will construct a "twin" column, with an _id suffix. This column has the same type as the type of the primary key of the model you target, and that column will thus contain the primary key of the model object you use. Note that you can use a different field to which you target by specifying the to_field=… parameter [Django-doc].

The ForeignKey itself thus does not exists at the database, that is the logic of Django that will use the primary of that object, and store that in a column with, by default, an _id suffix.

like image 113
Willem Van Onsem Avatar answered Oct 24 '22 01:10

Willem Van Onsem