1

I have Product model and my products don’t have available_quantity and prices field because these field are in another service. So I added custom field to my queryset.

This is my code;

for product in queryset:
    product.info_bundle = {
        'available_quantity': stock_info.get(product.stock_code),
        'prices': 100,
    }

I added my custom info_bundle field to queryset.

Problem is; I can’t order with queryset.order_by(‘avaliable_quantity’) because I added this. It’s not coming from database therefore SQL cant find the field.

Kaan Karaca
  • 190
  • 3
  • 12
  • 2
    Where does avaliable_quantity quantity come from? Do you have it stored in the database in another model? Is so, you can annotate your queryset to include avaliable_quantity field for each result and then order by it. If not, then you'd need to do the sorting in memory. – Ozgur Akcali Mar 13 '19 at 08:57
  • @OzgurAkcali avaliable_quantity is coming from another web service. It's separate from model and database. When I sorting in memory I should convert queryset to list and in get_queryset method I can't return list as a result I should return queryset. – Kaan Karaca Mar 13 '19 at 09:03

3 Answers3

1

You can not sort on the db level with a field you get from a 3rd party service. For your requirements, you'll need to sort in-memory. But as you suggested, when you do so you convert the queryset into a list. If I understood correctly you are using DRF and doing this sorting in the get_queryset method. So the following methods come to mind here:

  1. (Workaround) Return a list from get_queryset method, but override other methods of the view that use get_queryset method, and have them work with lists instead of querysets
  2. (Workaround) Do not do the sorting in get_queryset method, but override list method, and sort the results in-memory there before returning a response.
  3. Use a custom ordering filter in your view. The other 2 are workarounds, but with this approach it could be possible that you can build a solution that would be in line with the general flow of DRF. You might hit the same problem here though, as you'd be converting the queryset into a list while sorting.
Ozgur Akcali
  • 5,264
  • 2
  • 31
  • 49
0

You can't do that.

The order_by() is executed in DB level and it's only operated over either db fields or annotated fields.

The similar issue is also mentioned in a SO post, Filter a Django model property

JPG
  • 82,442
  • 19
  • 127
  • 206
0

You can transform this queryset into an array of dictionaries with this "custom field" inside every item. Like this:

products = []
for product in queryset:
    products.append({
        "product" = product,
        "available_quantity" = stock_info.get(product.stock_code),
        "prices" = 100
    })

So then you can order the array by the dictionary field. Like this:

new_sorted_list = sorted(products, key=lambda d: d["available_quantity"], reverse=True) 

# You can avoid the reverse parameter, it's for ASC or DESC results

Now you have your list ordered by a custom field.

I hope I can help you with this.