2016-05-23 8 views
1

Djangoでは、フィールド自体の値ではなく、フィールドがNoneであるかどうかで注文することは可能ですか?Django:日付が空であるかどうかの評価による注文

私はPython sorted()にQuerySetを送ることができますが、それを後続のフィルタリングのためのQuerySetとして保持したいと思います。ですから、私はQuerySet自体で注文することを好むでしょう。

例えば、私はtermination_dateフィールドを持っています。私はtermination_dateを持たないものを最初にソートしたいのですが、last_name、first_nameのような別のフィールドで注文したいと思います。

が、これは可能ですか私は新しいクエリセットにsorted()を含まIDを持つ全体の新しいクエリを実行し、実行すること、その後sorted()を使用して立ち往生していますか?私はこれを行うことができますが、オーバーヘッドを浪費せず、評価されるまで実行しないQuerySetsの美しさを利用することを望みます。

翻訳、どのように私は私のアプリはemployeeであると仮定するとジャンゴからこのSQLを取得することができ、私のモデルはEmployeeであり、それは三つのフィールド「FIRST_NAME(varchar型)」、「LAST_NAME(varchar型)」、および「TERMINATION_DATE(日)」を持っています:

SELECT 
    "employee_employee"."last_name", 
    "employee_employee"."first_name", 
    "employee_employee"."termination_date" 

FROM "employee_employee" 

ORDER BY 
    "employee_employee"."termination_date" IS NOT NULL, 
    "employee_employee"."last_name", 
    "employee_employee"."first_name" 

答えて

1

あなたはこのように、query expressionsで注文することができるはずです。

from django.db.models import IntegerField, Case, Value, When 

MyModel.objects.all().order_by(
    Case(
     When(some_field=None, then=Value(1)), 
     default=Value(0), 
     output_field=IntegerField(), 
    ).asc(), 
    'some_other_field' 
) 

それは周りいじるビットを必要とするかもしれないので、私はここでテストすることはできませんが、これはNULLを持つ行を置く必要がありますsome_fieldsome_fieldのものの後に行の各セットはsome_other_fieldでソートする必要があります。

CASE/WHENはあなたの質問に入れるほど面倒ですが、Django ORMに出力する方法はわかりません。多分誰かがより良い答えを持つでしょう。

+0

驚くべきことに、私は長年Djangoに取り組んできたことがあります。本当にありがとう、完璧に働いた! – Furbeenator

+0

@Furbeenator>これはかなり最近の追加です。私はDjango 1.7、おそらく1.8と思う。 djangoprojectチームは、Django ORMを組み合わせ可能なクエリ式で表現することにより、 '.extra()'メソッドを削除しようとしています。優れたカプセル化と移植性。 – spectras

+0

これは理にかなっています。私は1.3よりDjangoを保守していて、更新されたすべての最新のリリースノートを見ていません。私に恥がある...: -/ – Furbeenator

1

Spectrasの回答はうまくいきますが、あなたのレコードは「null or not」だけで注文します。

from django.db.models import Value 
from django.db.models.functions import Coalesce 

wayback = datetime(year=1, month=1, day=1) # or whatever date you want 
MyModel.objects 
     .annotate(null_date=Coalesce('date_field', Value(wayback))) 
     .order_by('null_date') 

これは、本質的にソートdate_field == Noneを持つすべてのレコードを持つフィールド'date_field'によっては順番になります。Coalesce - あなたの日付の順序でそれらを好きな場所に空の日付を置くことを可能にする短い方法がありますあたかも日付がwaybackであるかのように。これはPostgreSQLと完全に機能しますが、documentationに記述されているようにMySQLでraw sql castingが必要な場合があります。

+0

答えをくれてありがとう、@schwobaseggl!私は前に「合体」について聞いていなかった。それはまた、比較的新しい追加でなければならない。 @spectrasで言及された 'Coalesce'または' Case'ステートメントを使用するリソースの利点があるかどうかを知っていますか? – Furbeenator

+0

これは1.8で追加されました。それは、2つは非常に似ているように見えます:http://stackoverflow.com/questions/15523000/coalesce-or-case-more-efficient-and-or-standard。生成されたSQLを 'str(queryset.query)'でチェックすることができます。違いはありません。合体は基本的にはショートカットです。 – schwobaseggl

関連する問題