Django order_by a property









up vote
6
down vote

favorite












I'm faced with a problem wherein I'm trying to create a QuerySet with the results ordered not by a field on a model, but instead ordered by the result of a value returned by a method on the model.



To wit:



class MyModel(models.Model):

someAttributes = models.TextField(blank=True)

@property
def calculate_rating(self):
<do some calculation and return integer>


Given that, how can I construct a QuerySet that orders the results by the value for each instance as returned by calculate_rating()?



In trying to simply use order_by(), I get an error:




Cannot resolve keyword 'average_rating' into field.




Can anybody provide some ideas?










share|improve this question





















  • possible duplicate of Sorting a Django QuerySet by a property (not a field) of the Model
    – Anto
    May 8 '14 at 15:48














up vote
6
down vote

favorite












I'm faced with a problem wherein I'm trying to create a QuerySet with the results ordered not by a field on a model, but instead ordered by the result of a value returned by a method on the model.



To wit:



class MyModel(models.Model):

someAttributes = models.TextField(blank=True)

@property
def calculate_rating(self):
<do some calculation and return integer>


Given that, how can I construct a QuerySet that orders the results by the value for each instance as returned by calculate_rating()?



In trying to simply use order_by(), I get an error:




Cannot resolve keyword 'average_rating' into field.




Can anybody provide some ideas?










share|improve this question





















  • possible duplicate of Sorting a Django QuerySet by a property (not a field) of the Model
    – Anto
    May 8 '14 at 15:48












up vote
6
down vote

favorite









up vote
6
down vote

favorite











I'm faced with a problem wherein I'm trying to create a QuerySet with the results ordered not by a field on a model, but instead ordered by the result of a value returned by a method on the model.



To wit:



class MyModel(models.Model):

someAttributes = models.TextField(blank=True)

@property
def calculate_rating(self):
<do some calculation and return integer>


Given that, how can I construct a QuerySet that orders the results by the value for each instance as returned by calculate_rating()?



In trying to simply use order_by(), I get an error:




Cannot resolve keyword 'average_rating' into field.




Can anybody provide some ideas?










share|improve this question













I'm faced with a problem wherein I'm trying to create a QuerySet with the results ordered not by a field on a model, but instead ordered by the result of a value returned by a method on the model.



To wit:



class MyModel(models.Model):

someAttributes = models.TextField(blank=True)

@property
def calculate_rating(self):
<do some calculation and return integer>


Given that, how can I construct a QuerySet that orders the results by the value for each instance as returned by calculate_rating()?



In trying to simply use order_by(), I get an error:




Cannot resolve keyword 'average_rating' into field.




Can anybody provide some ideas?







django django-models






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked May 1 '13 at 16:45









Michael Place

2,00111416




2,00111416











  • possible duplicate of Sorting a Django QuerySet by a property (not a field) of the Model
    – Anto
    May 8 '14 at 15:48
















  • possible duplicate of Sorting a Django QuerySet by a property (not a field) of the Model
    – Anto
    May 8 '14 at 15:48















possible duplicate of Sorting a Django QuerySet by a property (not a field) of the Model
– Anto
May 8 '14 at 15:48




possible duplicate of Sorting a Django QuerySet by a property (not a field) of the Model
– Anto
May 8 '14 at 15:48












3 Answers
3






active

oldest

votes

















up vote
4
down vote



accepted










There is no way to do this. One thing you can do is to create a separate database field for that model and save the calculated rating in it. You can probably override the save method of the model and do the calculations there, after that you can only refer to the value.



You can also sort the returned QuerySet using Python sorted. Take into account that the sorting approach using the built-in sorted function increases a lot the computational complexity and it's not a good idea to use such code in production.



For more information you can check this answer: https://stackoverflow.com/a/981802/1869597






share|improve this answer





























    up vote
    10
    down vote













    order_by is for database stuff. Try to use sorted instead:



    sorted(MyModel.objects.all(), key=lambda m: m.calculate_rating)





    share|improve this answer



























      up vote
      0
      down vote













      The best way to achieve what you want, is by using the Case and When statements. This allows you to keep the final result in QuerySet instead of list ;)



      ratings_tuples = [(r.id, r.calc_rating) for r in MyModel.objects.all()] 
      s = sorted(ratings_tuples, key = lambda x: x[1]) # Sort by second tuple elem


      So here is our sorted list s that holds IDs and ratings of the elements in a sorted way



      pk_list = [idx for idx, rating in ratings_list] 
      from django.db.models import Case, When
      preserved = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(pk_list)])
      queryset = MyModel.objects.filter(pk__in=pk_list).order_by(preserved)


      Now, using Case and When statements, we are able to do the queryset sorting itself by the IDs from the list we already have. (Django Docs for details).

      Had a similar situation and needed a solution. So found some details on this post https://stackoverflow.com/a/37648265/4271452, it works.






      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',
        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%2f16322513%2fdjango-order-by-a-property%23new-answer', 'question_page');

        );

        Post as a guest















        Required, but never shown

























        3 Answers
        3






        active

        oldest

        votes








        3 Answers
        3






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes








        up vote
        4
        down vote



        accepted










        There is no way to do this. One thing you can do is to create a separate database field for that model and save the calculated rating in it. You can probably override the save method of the model and do the calculations there, after that you can only refer to the value.



        You can also sort the returned QuerySet using Python sorted. Take into account that the sorting approach using the built-in sorted function increases a lot the computational complexity and it's not a good idea to use such code in production.



        For more information you can check this answer: https://stackoverflow.com/a/981802/1869597






        share|improve this answer


























          up vote
          4
          down vote



          accepted










          There is no way to do this. One thing you can do is to create a separate database field for that model and save the calculated rating in it. You can probably override the save method of the model and do the calculations there, after that you can only refer to the value.



          You can also sort the returned QuerySet using Python sorted. Take into account that the sorting approach using the built-in sorted function increases a lot the computational complexity and it's not a good idea to use such code in production.



          For more information you can check this answer: https://stackoverflow.com/a/981802/1869597






          share|improve this answer
























            up vote
            4
            down vote



            accepted







            up vote
            4
            down vote



            accepted






            There is no way to do this. One thing you can do is to create a separate database field for that model and save the calculated rating in it. You can probably override the save method of the model and do the calculations there, after that you can only refer to the value.



            You can also sort the returned QuerySet using Python sorted. Take into account that the sorting approach using the built-in sorted function increases a lot the computational complexity and it's not a good idea to use such code in production.



            For more information you can check this answer: https://stackoverflow.com/a/981802/1869597






            share|improve this answer














            There is no way to do this. One thing you can do is to create a separate database field for that model and save the calculated rating in it. You can probably override the save method of the model and do the calculations there, after that you can only refer to the value.



            You can also sort the returned QuerySet using Python sorted. Take into account that the sorting approach using the built-in sorted function increases a lot the computational complexity and it's not a good idea to use such code in production.



            For more information you can check this answer: https://stackoverflow.com/a/981802/1869597







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited May 23 '17 at 12:25









            Community

            11




            11










            answered May 1 '13 at 16:59









            Jordan Jambazov

            2,1651132




            2,1651132






















                up vote
                10
                down vote













                order_by is for database stuff. Try to use sorted instead:



                sorted(MyModel.objects.all(), key=lambda m: m.calculate_rating)





                share|improve this answer
























                  up vote
                  10
                  down vote













                  order_by is for database stuff. Try to use sorted instead:



                  sorted(MyModel.objects.all(), key=lambda m: m.calculate_rating)





                  share|improve this answer






















                    up vote
                    10
                    down vote










                    up vote
                    10
                    down vote









                    order_by is for database stuff. Try to use sorted instead:



                    sorted(MyModel.objects.all(), key=lambda m: m.calculate_rating)





                    share|improve this answer












                    order_by is for database stuff. Try to use sorted instead:



                    sorted(MyModel.objects.all(), key=lambda m: m.calculate_rating)






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered May 1 '13 at 16:55









                    Alexandre

                    8901021




                    8901021




















                        up vote
                        0
                        down vote













                        The best way to achieve what you want, is by using the Case and When statements. This allows you to keep the final result in QuerySet instead of list ;)



                        ratings_tuples = [(r.id, r.calc_rating) for r in MyModel.objects.all()] 
                        s = sorted(ratings_tuples, key = lambda x: x[1]) # Sort by second tuple elem


                        So here is our sorted list s that holds IDs and ratings of the elements in a sorted way



                        pk_list = [idx for idx, rating in ratings_list] 
                        from django.db.models import Case, When
                        preserved = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(pk_list)])
                        queryset = MyModel.objects.filter(pk__in=pk_list).order_by(preserved)


                        Now, using Case and When statements, we are able to do the queryset sorting itself by the IDs from the list we already have. (Django Docs for details).

                        Had a similar situation and needed a solution. So found some details on this post https://stackoverflow.com/a/37648265/4271452, it works.






                        share|improve this answer
























                          up vote
                          0
                          down vote













                          The best way to achieve what you want, is by using the Case and When statements. This allows you to keep the final result in QuerySet instead of list ;)



                          ratings_tuples = [(r.id, r.calc_rating) for r in MyModel.objects.all()] 
                          s = sorted(ratings_tuples, key = lambda x: x[1]) # Sort by second tuple elem


                          So here is our sorted list s that holds IDs and ratings of the elements in a sorted way



                          pk_list = [idx for idx, rating in ratings_list] 
                          from django.db.models import Case, When
                          preserved = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(pk_list)])
                          queryset = MyModel.objects.filter(pk__in=pk_list).order_by(preserved)


                          Now, using Case and When statements, we are able to do the queryset sorting itself by the IDs from the list we already have. (Django Docs for details).

                          Had a similar situation and needed a solution. So found some details on this post https://stackoverflow.com/a/37648265/4271452, it works.






                          share|improve this answer






















                            up vote
                            0
                            down vote










                            up vote
                            0
                            down vote









                            The best way to achieve what you want, is by using the Case and When statements. This allows you to keep the final result in QuerySet instead of list ;)



                            ratings_tuples = [(r.id, r.calc_rating) for r in MyModel.objects.all()] 
                            s = sorted(ratings_tuples, key = lambda x: x[1]) # Sort by second tuple elem


                            So here is our sorted list s that holds IDs and ratings of the elements in a sorted way



                            pk_list = [idx for idx, rating in ratings_list] 
                            from django.db.models import Case, When
                            preserved = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(pk_list)])
                            queryset = MyModel.objects.filter(pk__in=pk_list).order_by(preserved)


                            Now, using Case and When statements, we are able to do the queryset sorting itself by the IDs from the list we already have. (Django Docs for details).

                            Had a similar situation and needed a solution. So found some details on this post https://stackoverflow.com/a/37648265/4271452, it works.






                            share|improve this answer












                            The best way to achieve what you want, is by using the Case and When statements. This allows you to keep the final result in QuerySet instead of list ;)



                            ratings_tuples = [(r.id, r.calc_rating) for r in MyModel.objects.all()] 
                            s = sorted(ratings_tuples, key = lambda x: x[1]) # Sort by second tuple elem


                            So here is our sorted list s that holds IDs and ratings of the elements in a sorted way



                            pk_list = [idx for idx, rating in ratings_list] 
                            from django.db.models import Case, When
                            preserved = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(pk_list)])
                            queryset = MyModel.objects.filter(pk__in=pk_list).order_by(preserved)


                            Now, using Case and When statements, we are able to do the queryset sorting itself by the IDs from the list we already have. (Django Docs for details).

                            Had a similar situation and needed a solution. So found some details on this post https://stackoverflow.com/a/37648265/4271452, it works.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Nov 10 at 0:03









                            Iulian Pinzaru

                            497




                            497



























                                 

                                draft saved


                                draft discarded















































                                 


                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function ()
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f16322513%2fdjango-order-by-a-property%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

                                How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

                                Syphilis

                                Darth Vader #20