Kaan Karaca
Kaan Karaca

Reputation: 190

How can I add custom field to queryset and sorted

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.

Upvotes: 1

Views: 3868

Answers (3)

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.

Upvotes: 0

Ozgur Akcali
Ozgur Akcali

Reputation: 5492

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.

Upvotes: 1

JPG
JPG

Reputation: 88649

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

Upvotes: 0

Related Questions