Is there ever any difference between using just a `foreign_key=` vs `foreign_key_id=` in Django's ORM?










2














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.










share|improve this question


























    2














    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.










    share|improve this question
























      2












      2








      2


      1





      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.










      share|improve this question













      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






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 10 at 0:57









      maxedison

      11k124882




      11k124882






















          1 Answer
          1






          active

          oldest

          votes


















          2














          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.






          share|improve this answer






















            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            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















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            2














            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.






            share|improve this answer



























              2














              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.






              share|improve this answer

























                2












                2








                2






                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.






                share|improve this answer














                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.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Nov 10 at 18:38

























                answered Nov 10 at 14:30









                Oluwafemi Sule

                10.8k1431




                10.8k1431



























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    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















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

                    Edmonton

                    Crossroads (UK TV series)