2016-08-17 3 views
-2

多くの場合、自分自身がオブジェクトに対してフィルタリングを行い、見つからなければNoneを返します。私は、通常、このような何かのオブジェクトをフィルタリングする場合しかし、私はこれを行う方法はDjangoでフィルタリングしてオブジェクトが存在するかどうかを確認するより良い方法

(コードの行の面で)本当に非効率です:

person = Person.objects.filter(id=id) 
if person: 
    person = Person.objects.get(id=id) 
else: 
    person = None 

をこれを行うには良い方法はあります?

私は私の最後に混乱を明確にするために編集しました。 フィルタクエリは、存在する場合は常に1つのオブジェクトを返す必要があります。

+0

'? – roganjosh

+1

または、合体演算子 'person = Person.objects.filter(name = name)またはNone'? 'Person.objects.filter(name = name)'が偽である場合、これはデフォルトで 'person = None'になります。 – roganjosh

+0

なぜif文でフィルターを繰り返すのか分かりません。 –

答えて

1

だけを1人を取得したい場合は、.get()を使用するか、Noneを返します。

try: 
    person = Person.objects.get(name=name) 
except (Person.DoesNotExist, Person.MultipleObjectsReturned) as e: 
    person = None 
+0

db(接続など)に何らかの問題があっても例外が発生するため、実際には悪い考えです。その人は簡単にそこにいるかもしれないが、あなたはNoneを返す。 –

+0

私はそれを修正することを確認します。 –

+0

これには1行の解決策がありますか?これは、これが共通のクエリである何かのための少しのコードであるように見えます。 –

1

if/elsepersonを2回割り当てている点で珍しいです。なぜ私は理解できません。私には2つの選択肢があります。

person = Person.objects.filter(name=name) 
if not person: 
    person = None 

それともcoalescing operatorと非常に簡潔にそれを作るために:

Person.objects.filter(name=name)がfalsyある場合 person = Noneを返します
person = Person.objects.filter(name=name) or None 

まず、あなたはif/elseだけifこのようにするを減らすことができます。

+0

これは、 '.get'を使うことができればうまくいくでしょう。そして、Noneが返されると予想されるとき、クエリはクラッシュしませんでした。 –

+0

@ JohnSmithあなたの質問に対する編集が全く違ったものになっています。もともと、あなたは 'if/else'で' filter'を繰り返しましたので、私の1ライナーはあなたが本来行っていたものとまったく同じです。今、それは意味をなさない。 – roganjosh

1

フィルター復帰リスト(空のリスト)ので、あなたは、あなたがリストを取得知っている、そしてなしで空のリストを交換したい場合:

persons = Person.objects.filter(name=name) 
if not any(person): 
    person = None 
# single person 
person = persons[0] # but there could be more than one 

が必要であれば一人

try: 
    person = Person.objects.get(name=name) 
except Person.MultipleObjectsReturned: 
    # do something if there is more Persons with that name 
    person = Person.objects.first() # for example return first person with that name 
except Person.DoesNotExist: 
    person = None # set person None 
+0

なぜ 'any()'が必要でしょうか?これは空リストであり、これは偽である。 'もし人でないなら'? – roganjosh

+0

もしそれが空でないならそれは完全なリストを繰り返します - >複数の人がいるなら**より遅くなります**任意の**関数return人が[0]なら真、人がいなければFalseを返します] –

+0

私は分かりません。 '[]'は常にfalseを返し、リストは単に空であるため何も繰り返されません。その中の項目を持つリストは 'True'を返しますが、チェックを行うにはリスト全体を反復する必要はありません。 – roganjosh

1

あなたはdocsからexists()

を使用することができます。

あなたが唯一の少なくとも1つの結果が存在するかどうかを決定します(実際のオブジェクトを必要としない)場合、それはより多くのです効率的にexists()を使用します。

entry = Entry.objects.get(pk=123) 
if some_queryset.filter(pk=entry.pk).exists(): 
    print("Entry contained in queryset") 
else: 
    return None 

コードの行が懸念される場合は、この少しを短縮することができます。しかし:

また、some_querysetは、その後、some_queryset.existsを使用して、まだ評価されていないが、あなたはそれはいくつかのポイントになりますことを知っている 場合() は、より全体的な仕事(の存在のための1つのクエリを実行しますその結果を取得して が返されたかどうかを確認するbool(some_queryset)を単に使用するのではなく、 余分なものをチェックして後で結果を取得する)。

+0

私はあなたの質問のタイトルを、この回答でお伝えします。オブジェクト*が存在するかどうかをどのように伝えますか? –

1

このようにすることはできません。

person = Person.objects.get(name=name) 

例外が発生します。

try: 
    person = Person.objects.get(name=name) 
except Person.MultipleObjectsReturned: 
    person = Person.objects.first() 
except Person.DoesNotExist: 
    person = None 

しかし、ここで最高のものは、使用することです:あなたは何ができるか

がある

person`ない場合
some_queryset.filter(pk=entry.pk).exists() 
関連する問題