1. ホーム

django ORM 条件付きフィルタリング、および複数テーブルの結合クエリ、逆クエリ、フィールドの区別

2022-03-02 03:03:04
1.複数テーブルの結合クエリ。これを知ったとき、djangoはNXすぎると思いました。



  クラスA(models.Model)。



    name = models.CharField(u'name')です。



  クラスB(models.Model)。



    aa = models.ForeignKey(A)です。



B.objects.filter(aa__name__contains='searchtitle')







1.5逆引きと称して後でレコード1.5を挿入し、即座に気付いた時にはdjangoはNX夫人過ぎると思いました。



  class A(models.Model):



    name = models.CharField(u'name')です。



  クラスB(models.Model)。



    aa = models.ForeignKey(A,related_name="FAN")



    bb = models.CharField(u'name')です。



  A: A.objects.filter(FAN__bb='XXXX'), all know the role of related_name, A.FAN.all() is a foreign key, but the front of such use is to query all (B.aa = A and B. B.). bb=XXXX)のインスタンスを調べ、さらに__様々な関係によって調べることです。最初の用途は、Aのすべてのインスタンス(B.aa=A、B.bb=XXXX)を調べ、さらに__様々な関係によって調べることができます。







2. 2. querySetを条件付きで選ぶ場合、filterは=、excludeは! =.



querySet.distinct() 重複を解消する。



__exact 'aaa'のような正確な等号



 __iexact 正確に等しい 無視する場合 'aaa' のような場合



 __contains '%aaa%'のようなものを含む。



 __icontains containsは'%aaa%'のようなケースを無視しますが、sqliteの場合、containsはicontainsと同じ効果を発揮します。



__gt は以下より大きい



gteは以上である。



__lt より小さい



lteは以下となります。



リスト範囲内に存在する



__startswith start with... で始まる。



__istartswith は...で始まります。無視する場合



__endswith は...で始まります。で終わる



__iendswith は...で終わる、大文字小文字を無視した終わり方



__range ...の範囲内



__year 日付フィールドの年号



月 日付フィールドの月



__day 日付フィールドの日



__isnull=True/False











>> q1 = Entry.objects.filter(headline__startswith="What")



>> q2 = q1.exclude(pub_date__gte=datetime.date.today())



>> q3 = q1.filter(pub_date__gte=datetime.date.today())



>>> q = q.filter(pub_date__lte=datetime.date.today()の場合。)



>>> q = q.exclude(body_text__icontains="食品")。







つまり、q1.filter(pub_date__gte=datetime.date.today())は時間 >=now、q1.exclude(pub_date__gte=datetime.date.today())は <=nowを意味するのです。







2013/12/12に追記しました。



django モデルでフィールドの識別値を取得します"。これは select distinct xxx from table_name ...です。こんな感じの関数です。valuesを使うとValuesQuerySet(N個のdictsのリストのような形)が生成されるので、結局、クエリ操作の時だけqueryset系列が使われるので、ビッグデータに対する追加のパフォーマンスインパクトはないのでしょう。



xxxx.objects.values("フィールド名").distingu()



#または



xxxx.objects.distinct().values("field_name")



この2つの生成されたSQL文は同じものです。 http://blog.csdn.net/tsbob/article/details/1340293 .







キャッシングについて



querysetは、a = A.objects.all(),print [i for i in a]とキャッシュされています。printが最初に実行されると、データベースに問い合わせが行われ、その結果がquerysetの組み込みキャッシュに保存され、printが再び実行されると、キャッシュから取得されます。



querysetが空かどうかだけ判断できればよい場合も多いので、 1. if queryset:pass 2. if queryset.count>0:pass 3. if queryset.exists():pass とすることができる。の3つの方法で、順番に性能が向上します。



querysetが非常に大きい場合、キャッシュが問題になることがあります。この時点でqueryset.iterator()を使用することができ、イテレータの有用性は説明されません、彼らは特定のニーズに応じて使用されています。