10👍
This is explained in the docs:
https://docs.djangoproject.com/en/dev/ref/models/fields/#database-representation
In the database there is only client_id
field (single underscore)
On the model instance you will have client
attribute, when you access it this will cause Django to load the related object from the db and instantiate as another model instance.
You will also have client_id
attribute (one underscore) which has the primary key value of the related object, as stored in the db field.
When doing ORM queries you are able to use client__id
(double underscore) syntax to lookup against fields on the related model, eg you could also do client__name
if Client
model had a name
field. This will become a SQL JOIN query across both models.
eg
Job.objects.get(client__id=1)
Job.objects.filter(client__name='John')
client = Client.objects.get(pk=1)
Job.objects.get(client=client)
11👍
What you are probably talking about is client
and client_id
(single underscore).
The client_id
attribute is a regular (integer) attribute. This is the foreign key that is saved to the database. You will only ever see a client_id
column in the database, even though you specify the ForeignKey
as client
.
The client
attribute is an object descriptor instance. It is a special class that overrides the __get__
and __set__
methods, so settings and accessing that attributes invokes that class’s methods. This is the magic that gives you access to the actual related model instance. __get__
will retrieve the correct model instance from the database if it isn’t loaded already, based on the client_id
attribute. __set__
will also set the client_id
attribute to the primary key of the related object, so that client_id
is always up-to-date.
Note that this attribute is also available in query lookups, and is quite handy. E.g., if you have just the primary key of a foreign object, and not the model instance itself, the following queries look very similar:
job = Job.objects.filter(client__id=pk)
job = Job.objects.filter(client_id=pk)
However, underneath the first query accesses an attribute on the related object (double underscore) and performs an OUTER JOIN
. The second query only ever accesses a local attribute, thus not having to perform the OUTER JOIN
statement and saving performance.
- Django – links generated with {% url %} – how to make them secure?
- Django backup strategy with dumpdata and migrations
- Django QuerySet object has no attribute 'objects
3👍
j.client
gives you the models.Model
object. You can access it’s properties like …
client = j.client
id = client.id
name = client.name
But there should not be a j.client__id
field. You should use j.client.id
to get the id
field. Although you can use j.client__id
field to do filters and such.
So,
id = j.client.id # good
id = j.client__id # bad
and
job = Job.objects.get(client__id=1) # good
job = Job.objects.get(client.id=1) # bad
- Django: datetime filter by date ignoring time
- Django: foreign key value in a list display admin
- Custom label on ModelChoiceField form field
- Where is Pip3 Installing Modules?
- Is it possible to stop Django from creating .pyc files, whilst in development?