21.QuerySetAPI

 

クエリセットAPI:

私たちは通常、モデル名.objectsによって運営され、クエリの時間を行います。実際には、モデル名の.objects django.db.models.manager.Managerオブジェクトである、マネージャーこのクラスは、クラスの「シェル」で、彼はすべてのプロパティとメソッドではありません。彼の方法は、全てのPythonの方法によって動的にクラスクエリセットからコピー、追加されます。

モデル.objects:

このオブジェクトはdjango.db.models.manager.Managerオブジェクト、このクラスはシェルクラスであり、上記のすべての方法は、彼からのものQuerySetがあり、その上のクラスのコピー。限り我々が学んだようQuerySetに、これはobjects使用する方法を知っています。
Manager出典分析:

class_name = "BaseManagerFromQuerySet"

class_dict = {
    '_queryset_class': QuerySet
}

class_dict.update(cls._get_queryset_methods(QuerySet))

# type动态的时候创建类
# 第一个参数是用来指定创建的类的名字。创建的类名是:BaseManagerFromQuerySet
# 第二个参数是用来指定这个类的父类。
# 第三个参数是用来指定这个类的一些属性和方法
return type(class_name,(cls,),class_dict)

_get_queryset_methods:这个方法就是将QuerySet中的一些方法拷贝出来

フィルタ

データは条件を満たすように抽出され、新たなクエリセットを返します。具体的なフィルタは、どのような条件の問い合わせを提供することができます

除外する

データを除外する条件を満たし、かつ、新たなクエリセットを返しています。次のようにサンプル・コードは次のとおりです。

 Article.objects.exclude(title__contains='hello')


このコードは、タイトルが本のハローの抽出物を含有しないことを意味します。

注釈を付けます

クエリセットの各オブジェクトは、新しいフィールドのクエリ式(集合関数、F式、Q式、のFunc式等)を使用して追加されます。次のようにサンプル・コードは次のとおりです。

articles = Article.objects.annotate(author_name=F("author__name"))


上記のコードは、この記事の年齢の作者を表示するために使用される各オブジェクトにauthor__nameフィールドを追加する必要があります。

集計

集計関数。

ORDER_BY:

# 根据创建的时间正序排序
articles = Article.objects.order_by("create_time")
# 根据创建的时间倒序排序
articles = Article.objects.order_by("-create_time")
# 根据作者的名字进行排序
articles = Article.objects.order_by("author__name")
# 首先根据创建的时间进行排序,如果时间相同,则根据作者的名字进行排序
articles = Article.objects.order_by("create_time",'author__name')

注意してくださいが複数、ということでorder_by、後者の並べ替えを使用して、仕分けルールを先行することによって動揺します。たとえば、次のコード:

articles = Article.objects.order_by("create_time").order_by("author__name")

彼は代わりに記事を作成するために時間を使っての、作成者の名前に基づいてソートされます。
もちろん、モデルも定義することができMetaクラス定義orderingのデフォルトのソート順を指定します。次のようにサンプル・コードは次のとおりです。

    class Meta:
        db_table = 'book_order'
        ordering = ['create_time','-price']

また、することができますannotate定義されたフィールドをソートします。たとえば、次のように、サンプルコード、ソートされた本の売り上げを達成するために:

books = Book.objects.annotate(order_nums=Count("bookorder")).order_by("-order_nums")
    for book in books:
        print('%s/%s'%(book.name,book.order_nums))

values戻り値もありQuerySet、目標が、それQuetySetと一緒にインストールされていないモデルではなく、一つですdict辞書。

我々はこのモデルに関連付けられているオブジェクトのプロパティを抽出したい場合は、検索順序でも可能であり、filter使用量が次のようにサンプルコードと同じです。:

books = Book.objects.values("id","name","author__name")


上記抽出されauthorたモデルの中でname次のようにキーワードのパラメータのサンプルコードを使用することができ、私たちは名前をしたくない場合は、あなたが名前を変更したい、フィールド:

books = Book.objects.values("id","name",author_name=F("author__name"))


カスタム名ではなく、モデル自体、上記の例で同じによって所有フィールド、author_name名前が呼ばれた場合authorので「、エラーが出るでしょBook自体に呼ばれるフィールドを持っていますauthor

values、私が各書籍は、次のサンプルコードの販売を取得したいなどの新しいフィールドの集計関数を形成することも可能です。

books = Book.objects.values("id","name",order_nums=Count("bookorder"))

あなたが呼び出す場合valuesの方法を以下のように、任意のパラメータが渡されていない場合には、辞書が形成されているすべてのモデルのフィールドとサンプルコードの対応する値を取得します。

books = Book.objects.values()

values_list

D values同じアクションが、このメソッドが戻る。QuerySet、辞書がインストールされていないが、タプル、次のサンプルコード:

books = Book.objects.values_list("id","name")


次に、上記のコードの結果を返しています。

(1,"西游记")

する場合values_listのみ1フィールドを指定し、その後、我々は指定することができflat=True、このような結果は、タプルに戻されていないが、このフィールドの値は、次のサンプルコード:

books = Book.objects.values_list("name",flat=True)


返される結果は以上です。

`三国演义`


フラットのみそれ以外の場合はエラーになり、一方のフィールドのみの場合に使用することができ、ことに注意してください。

すべてのメソッド

クエリモデル内のすべてのデータ、リターンQuerySetオブジェクトそのQuerySet(等濾過、など)の任意の変更なしにオブジェクト

ワンタイムデータが抽出されている他のテーブルに関連付けることができたときに、後で時間に関連付けられたデータテーブルにアクセスすることができ、再びデータベースを見つけることができませんので、あなたには、いくつかのオーバーヘッドを保存することができ、テーブル内のデータを検索します。例コードは以下の通りであります:

books = Book.objects.select_related("author","publisher")
for book in books:
    print(book.author.name)
    # 因为在提取book的时候,使用了select_related,那么以后在访问book.author的时候,不会再次向数据库重新发起查询


注:この方法は、唯一の種類多、又は多対達成それは使用できないが、使用されるべきである場合にのために、キーに関連付けられたオブジェクトの外で使用することができるprefetch_related達成します。

この方法は、に似ているselect_related方法を見つけるために、事前にデータを照会して抽出するために使用されている場合。しかし、この方法は多く、非外部キー状況に多くを解決するために使用される。この方法は、2つのクエリが生成されますので、外部キークエリモデルが使用されている場合select_related、クエリは非多くまたは外部キーが、使用する場合であればprefetch_related、次のサンプルコードは:

books = Book.objects.prefetch_related("bookorder_set")


なお:使用中prefetch_related見つけるためにboororder_set、例えば、任意の操作を実行しないことをお勧めしますfilter、またはNクエリよりも多くを生産する、など次のコードのようにクエリのパフォーマンスが間違っている影響を与えます。

books = Book.objects.prefetch_related("bookorder_set")
for book in books:
    print(book.name)
    # 这个地方如果对bookorder_set进行了操作,那么就又会产生新的sql语句,前面的prefetch_related就相当于白做了
    oredrs = book.bookorder_set.fliter(price__gte=90)
    for order in orders:
        print(order.id)


あなたがしたい場合は、操作前のセットを見つけることですので、我々は使用することができdjango.db.models.Prefetch、次のように、サンプルコードを完了するには:

# 先使用Prefetch把查找的条件写好,在放到prefetch_related中
from django.db.models import Prefetch
prefetch = Prefetch("bookorder_set",queryset=Bookorder.objects.filter(price__gte=90))
books = Book.objects.prefetch_related(prefetch)
for book in books:
    print(book.name)
    orders = book.bookorder_set.all()
    for order in orders:
        print(order.id)

延期和のみ

どちらの方法でも返しQuerySet、これはQuerySetすべてのモデルではなく、フィールドでインストール
1 defer:このメソッドは、伝えるために使用されているORM。特定のフィールドをフィルタリングする際のモデルクエリで、
2 only:このメソッドは使用されています伝えるONR。あなただけの特定のフィールドを抽出することができ、モデルを照会、
注:使用してdefer、将来的には、このフィールドを使用して、フィールドを再起動しますリクエストので、慎重に操作することがonly次のように共感サンプルコードも:

articles = list(Article.objects.defer("title"))
for article in articles:
    # 因为在上面提取的时候过滤了title
    # 这个地方重新获取title,将重新向数据库中进行一次查找操作
    print(article.title)
for sql in connection.queries:
    print('='*30)
    print(sql)

取得する

データ収集の条件を満たして、それが特定のモデルを返します。この機能は、一つだけのデータを返すことができ、およびデータへの条件の数は、このメソッドはMultipleObjectsReturnedエラーをスローした場合、任意のデータの不在を与えられた場合、それはDoesNotExitエラーがスローされます。したがって、この方法は、データのみを取得することができ、かつ1つのみを持つことができます。

作ります

データを作成し、データベースに保存されました。このメソッドは、最初に指定されたモデルでオブジェクトを作成し、オブジェクトのsaveメソッドを呼び出すことと等価です。次のようにサンプル・コードは次のとおりです。

article = Article(title='abc')
article.save()

# 下面这行代码相当于以上两行代码
article = Article.objects.create(title='abc')

bulk_create

関係なく、データの多くの部分は、SQL文が解決する方法を、複数のデータを作成していません

get_or_create

与えられた条件のデータならば、それが直接データを抽出するために出てきます。データが与えられた条件ではない場合、それはデータを作成し、バックデータが返されます。

カウント

count:抽出されたデータの数を取得します。あなたはデータの総数を知りたい場合は、それを使用することをお勧めしますcount代わりに使用するのでは、len(articles)これを。カウントは一番下に使用されているのでselect count(*)、はるかに効率的lenの機能を使用するよりもある、達成します。

最初の和最後

戻り値は、最初と最後のデータをクエリセット、戻り値はデータモデルです。

exisit

exists:データの条件があるかどうかを決定します。条件の要素があるかどうかを判断するには、使用することをお勧めしますexists使用するよりも、それをcountどちらかを評価QuerySetはるかに効果的。次のようにサンプル・コードは次のとおりです。

if Article.objects.filter(title__contains='hello').exists():
    print(True)
比使用count更高效:
if Article.objects.filter(title__contains='hello').count() > 0:
    print(True)
也比直接判断QuerySet更高效:
if Article.objects.filter(title__contains='hello'):
    print(True)

明確な

distinct:これらの重複データを取り除くために。基礎となるデータベースMySQLは、それが任意のパラメータを渡すことができない場合、このメソッドは使用されています。たとえば、書籍の以上80元の販売価格のすべてを抽出し、それらの重複を削除するには、使用することができdistinct、次のように私たちは、サンプルコードを達成するのを助けるために:

books = Book.objects.filter(bookorder__price__gte=80).distinct()


場合は、それを注意してくださいdistinctする前に使用しorder_by、それがあるため、order_by抽出されますorder_by指定したフィールドを、その再使用がdistinct複数のフィールドの裏に基づいて行われますので、私はそれらのデータが削除されます繰り返すことはしません。次のようにサンプル・コードは次のとおりです。

orders = BookOrder.objects.order_by("create_time").values("book_id").distinct()


異なるとともにため使用ORDER_BYの上記のコードので、抽出book_idを繰り返すであろう。

更新

使い捨てが完了したすべてのデータの更新を置くことができます
update:更新操作を、下部には、SQLに取っているupdateコマンド。例えば、我々はすべてのカテゴリフィールドの空の記事の記事は、デフォルトのカテゴリに更新されたいです。次のようにサンプル・コードは次のとおりです。

Article.objects.filter(category__isnull=True).update(category_id=3)


この方法は、更新ロジックを取っていることに注意してください。更新は行われません後そのため、データベースに保存されたsaveメソッドを、それが更新されませんauto_nowフィールドの設定を。

削除

delete:条件を満たすために、すべてのデータを削除します。データを削除して、に注意を払うon_delete指定取り扱います。

スライス

スライス:時々、私たちはデータを見つけ、それの一部だけがあるかもしれません。そこで、今回は、それは、私たちが完全に支援するための操作をスライスすることができます。クエリセットのスライス操作だけで、スライス操作は同じであるリスト。次のようにサンプル・コードは次のとおりです。

books = Book.objects.all()[1:3]
for book in books:
    print(book)


スライシング操作は、スライス操作を行うには、データベースから抽出されたすべてのデータはありません。しかし、データベースレベルでOFFSET LIMIEの使用は、私たちは完全に役立ちます。あなただけのときにそれらの一部のデータを取る必要があるのであれば、あなたがスライシング操作を使用することをお勧めします。

Djangoのクエリセットを実行するためにSQLに変換されます場合は:

すぐにSQL文が実行に変換されないクエリセットオブジェクトを生成します。
例えば、我々は、ブックリストの下のすべての書籍を取得します:

books = Book.objects.all()
print(connection.queries)


私たちは、印刷connection.quries印刷時に空のリストであることがわかります。クエリセット上記の説明は、実際には実行されません。
クエリセットは、SQL文の次のような場合に変換されます。

  1. 迭代:クエリセットオブジェクトを横断するとき、これは、SQL文を実行して初めてとなる、その後、結果が反復処理に戻りました。たとえば、次のコードでは、SQL文に変換されます。
     for book in Book.objects.all():
         print(book)
    
  2. 使用步长を行うに切片操作を:クエリセットは、同じ操作を行うのリストのようにスライスすることができます。スライス作業自体はSQL文を実行しませんんが、ステップはスライシング動作時間を行っている場合ならば、それはすぐにSQL文を実行します。それはもはや、それ以外の場合はエラーになり、スライスした後に行うために、フィルタメソッドを実行することができ、注意すべきではありません。

  3. コールlen函数:SQL文を実行しますデータの総数を取得するために、LEN関数内でクエリセットを呼び出します。

  4. コールlist函数:コールリスト機能は、すぐにSQL文を実行するオブジェクトのリストにクエリセットオブジェクトを変換するために使用されます。

  5. 判断:あなたはクエリセットを判断した場合は、すぐにSQL文を実行します。

おすすめ

転載: www.cnblogs.com/ys-python/p/11266224.html