Is there ever any difference between using just a `foreign_key=` vs `foreign_key_id=` in Django's ORM?
up vote
2
down vote
favorite
There does not appear to be a difference between the following:
ModelA.objects.filter(modelb_id=a_model_id)
ModelA.objects.filter(modelb=a_model_id)
Printing out the SQL that Django generates for both cases shows that it is the same. However, I haven't been able to find this officially documented anywhere, and I'm therefore concerned that there may be some case where using just modelb
might result in something different from modelb_id
.
I'm especially interested in someone pointing me to an official source that confirms these things are equivalent.
python sql django orm
add a comment |
up vote
2
down vote
favorite
There does not appear to be a difference between the following:
ModelA.objects.filter(modelb_id=a_model_id)
ModelA.objects.filter(modelb=a_model_id)
Printing out the SQL that Django generates for both cases shows that it is the same. However, I haven't been able to find this officially documented anywhere, and I'm therefore concerned that there may be some case where using just modelb
might result in something different from modelb_id
.
I'm especially interested in someone pointing me to an official source that confirms these things are equivalent.
python sql django orm
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
There does not appear to be a difference between the following:
ModelA.objects.filter(modelb_id=a_model_id)
ModelA.objects.filter(modelb=a_model_id)
Printing out the SQL that Django generates for both cases shows that it is the same. However, I haven't been able to find this officially documented anywhere, and I'm therefore concerned that there may be some case where using just modelb
might result in something different from modelb_id
.
I'm especially interested in someone pointing me to an official source that confirms these things are equivalent.
python sql django orm
There does not appear to be a difference between the following:
ModelA.objects.filter(modelb_id=a_model_id)
ModelA.objects.filter(modelb=a_model_id)
Printing out the SQL that Django generates for both cases shows that it is the same. However, I haven't been able to find this officially documented anywhere, and I'm therefore concerned that there may be some case where using just modelb
might result in something different from modelb_id
.
I'm especially interested in someone pointing me to an official source that confirms these things are equivalent.
python sql django orm
python sql django orm
asked Nov 10 at 0:57
maxedison
11k124881
11k124881
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
TLDR: It's better to consider the recommendation of the authors of the framework and use model field names.
Database Representation
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. Reference
Model fields subclass django.db.models.fields.Field
. The Field
class has an attname
field which is documented internally in the source code as the way to resolve the attribute to use on the model object.
# A guide to Field parameters:
#
# * name: The name of the field specified in the model.
# * attname: The attribute to use on the model object. This is the same as
# "name", except in the case of ForeignKeys, where "_id" is
# appended.
# * db_column: The db_column specified in the model (or None).
# * column: The database column for this field. This is the same as
# "attname", except if db_column is specified.
#
# Code that introspects values, or does other dynamic things, should use
# attname. For example, this gets the primary key value of object "obj":
#
# getattr(obj, opts.pk.attname)
As part of the execution flow to converting the QuerySet.filter
names in the kwargs for the compiled SQL query, the names are translated to PathInfo
tuples containing the model fields for the respective names.
On Line 1354 for django.db.models.sql.query.Query
, is the following line:
field = opts.get_field(name)
Now opts
is an instance of django.db.models.options.Options
and the get_field
method delegates to _forward_fields_map
or fields_map
cached properties.
When you look at the implementation of those two properties, you see that they return a dictionary mapping field.name
to field
together with field.attname
to field
.
This makes it so that modelb_id
or modelb
resolves to the model field from either of the cached properties.
In my opinion, it doesn't matter that modelb_id
or modelb
is passed as a keyword argument to QuerySet.filter
. Only that the former keyword requires knowledge of an implementation detail.
However it's better to consider the recommendation of the authors of the framework and use the model field names.
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
TLDR: It's better to consider the recommendation of the authors of the framework and use model field names.
Database Representation
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. Reference
Model fields subclass django.db.models.fields.Field
. The Field
class has an attname
field which is documented internally in the source code as the way to resolve the attribute to use on the model object.
# A guide to Field parameters:
#
# * name: The name of the field specified in the model.
# * attname: The attribute to use on the model object. This is the same as
# "name", except in the case of ForeignKeys, where "_id" is
# appended.
# * db_column: The db_column specified in the model (or None).
# * column: The database column for this field. This is the same as
# "attname", except if db_column is specified.
#
# Code that introspects values, or does other dynamic things, should use
# attname. For example, this gets the primary key value of object "obj":
#
# getattr(obj, opts.pk.attname)
As part of the execution flow to converting the QuerySet.filter
names in the kwargs for the compiled SQL query, the names are translated to PathInfo
tuples containing the model fields for the respective names.
On Line 1354 for django.db.models.sql.query.Query
, is the following line:
field = opts.get_field(name)
Now opts
is an instance of django.db.models.options.Options
and the get_field
method delegates to _forward_fields_map
or fields_map
cached properties.
When you look at the implementation of those two properties, you see that they return a dictionary mapping field.name
to field
together with field.attname
to field
.
This makes it so that modelb_id
or modelb
resolves to the model field from either of the cached properties.
In my opinion, it doesn't matter that modelb_id
or modelb
is passed as a keyword argument to QuerySet.filter
. Only that the former keyword requires knowledge of an implementation detail.
However it's better to consider the recommendation of the authors of the framework and use the model field names.
add a comment |
up vote
2
down vote
accepted
TLDR: It's better to consider the recommendation of the authors of the framework and use model field names.
Database Representation
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. Reference
Model fields subclass django.db.models.fields.Field
. The Field
class has an attname
field which is documented internally in the source code as the way to resolve the attribute to use on the model object.
# A guide to Field parameters:
#
# * name: The name of the field specified in the model.
# * attname: The attribute to use on the model object. This is the same as
# "name", except in the case of ForeignKeys, where "_id" is
# appended.
# * db_column: The db_column specified in the model (or None).
# * column: The database column for this field. This is the same as
# "attname", except if db_column is specified.
#
# Code that introspects values, or does other dynamic things, should use
# attname. For example, this gets the primary key value of object "obj":
#
# getattr(obj, opts.pk.attname)
As part of the execution flow to converting the QuerySet.filter
names in the kwargs for the compiled SQL query, the names are translated to PathInfo
tuples containing the model fields for the respective names.
On Line 1354 for django.db.models.sql.query.Query
, is the following line:
field = opts.get_field(name)
Now opts
is an instance of django.db.models.options.Options
and the get_field
method delegates to _forward_fields_map
or fields_map
cached properties.
When you look at the implementation of those two properties, you see that they return a dictionary mapping field.name
to field
together with field.attname
to field
.
This makes it so that modelb_id
or modelb
resolves to the model field from either of the cached properties.
In my opinion, it doesn't matter that modelb_id
or modelb
is passed as a keyword argument to QuerySet.filter
. Only that the former keyword requires knowledge of an implementation detail.
However it's better to consider the recommendation of the authors of the framework and use the model field names.
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
TLDR: It's better to consider the recommendation of the authors of the framework and use model field names.
Database Representation
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. Reference
Model fields subclass django.db.models.fields.Field
. The Field
class has an attname
field which is documented internally in the source code as the way to resolve the attribute to use on the model object.
# A guide to Field parameters:
#
# * name: The name of the field specified in the model.
# * attname: The attribute to use on the model object. This is the same as
# "name", except in the case of ForeignKeys, where "_id" is
# appended.
# * db_column: The db_column specified in the model (or None).
# * column: The database column for this field. This is the same as
# "attname", except if db_column is specified.
#
# Code that introspects values, or does other dynamic things, should use
# attname. For example, this gets the primary key value of object "obj":
#
# getattr(obj, opts.pk.attname)
As part of the execution flow to converting the QuerySet.filter
names in the kwargs for the compiled SQL query, the names are translated to PathInfo
tuples containing the model fields for the respective names.
On Line 1354 for django.db.models.sql.query.Query
, is the following line:
field = opts.get_field(name)
Now opts
is an instance of django.db.models.options.Options
and the get_field
method delegates to _forward_fields_map
or fields_map
cached properties.
When you look at the implementation of those two properties, you see that they return a dictionary mapping field.name
to field
together with field.attname
to field
.
This makes it so that modelb_id
or modelb
resolves to the model field from either of the cached properties.
In my opinion, it doesn't matter that modelb_id
or modelb
is passed as a keyword argument to QuerySet.filter
. Only that the former keyword requires knowledge of an implementation detail.
However it's better to consider the recommendation of the authors of the framework and use the model field names.
TLDR: It's better to consider the recommendation of the authors of the framework and use model field names.
Database Representation
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. Reference
Model fields subclass django.db.models.fields.Field
. The Field
class has an attname
field which is documented internally in the source code as the way to resolve the attribute to use on the model object.
# A guide to Field parameters:
#
# * name: The name of the field specified in the model.
# * attname: The attribute to use on the model object. This is the same as
# "name", except in the case of ForeignKeys, where "_id" is
# appended.
# * db_column: The db_column specified in the model (or None).
# * column: The database column for this field. This is the same as
# "attname", except if db_column is specified.
#
# Code that introspects values, or does other dynamic things, should use
# attname. For example, this gets the primary key value of object "obj":
#
# getattr(obj, opts.pk.attname)
As part of the execution flow to converting the QuerySet.filter
names in the kwargs for the compiled SQL query, the names are translated to PathInfo
tuples containing the model fields for the respective names.
On Line 1354 for django.db.models.sql.query.Query
, is the following line:
field = opts.get_field(name)
Now opts
is an instance of django.db.models.options.Options
and the get_field
method delegates to _forward_fields_map
or fields_map
cached properties.
When you look at the implementation of those two properties, you see that they return a dictionary mapping field.name
to field
together with field.attname
to field
.
This makes it so that modelb_id
or modelb
resolves to the model field from either of the cached properties.
In my opinion, it doesn't matter that modelb_id
or modelb
is passed as a keyword argument to QuerySet.filter
. Only that the former keyword requires knowledge of an implementation detail.
However it's better to consider the recommendation of the authors of the framework and use the model field names.
edited Nov 10 at 18:38
answered Nov 10 at 14:30
Oluwafemi Sule
9,7811330
9,7811330
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53235094%2fis-there-ever-any-difference-between-using-just-a-foreign-key-vs-foreign-key%23new-answer', 'question_page');
}
);
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password