Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

django - ordering queryset by a calculated field

I want to have a model with calculated fields that I can apply sorting on. For example, let's say that I have the following model:

class Foo(models.Model):
    A = models.IntegerField(..)
    B = models.IntegerField(..)
    C = models.ForeignKey(..)

I want to have a D and an E field that are calculated by the following formulas:

  1. D = A - B
  2. E = A - X (where X is a field of the relevant record of model C)

Implementing this would be trivial if I didn't need to apply sorting; I would just add properties to the model class. However, I need ordering by these fields.

A solution is to fetch all records into memory and do the sorting there, which I conceive a last resort (it will break things regarding pagination).

Is there a way to achieve what I'm trying? Any guidance is appreciated.

EDIT: Denormalization is a no-go. The value of field X changes very frequently and a lot of Foo records are related to one record of model C. An update of X will require thousands of updates of E.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Please refrain from using extra() as it's meant to be deprecated in the future.

Since Django 1.7 you can use a combination of annotate() and order_by() to achieve this

Foo.objects.annotate(ordering=F('A') - F('B')).order_by('ordering')

There's also ungoing work to allow expressions to be used all over the ORM so the following should work in future versions of Django:

Foo.objects.order_by(F('A') - F('B'))

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...