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?
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.
str function in a django model returns a string that is exactly rendered as the display name of instances for that model.
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).
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 theCar
model will have amanufacturer_id
column. (You can change this explicitly by specifyingdb_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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With