1. ホーム
  2. ジャンゴ

Djangoデータベースのクエリセット操作

2022-03-02 17:56:30
aaa'のような__exact正確な等しい
正確なイコールは、'aaa'のようなケースを無視します。
__contains '%aaa%'のようなものを含む。
__icontains containsは'%aaa%'のようなケースを無視しますが、sqliteではcontainsはicontainsと同じ効果になります。
__gt より大きい
gteが以上であること
__lt より小さい
lte 以下
リスト内に存在する__in
__startswith start with...で始まる。
__istartswithは...で始まります。無視する場合
__endswithは...で始まります。で終わる
__iendswith ends with... endings, ignoring case
__range 範囲は...以内
__year 日付フィールドの年
月 日付フィールドの月
__day 日付フィールドの日数
__isnull=True/False
isnull=Trueと__exact=Noneの違いについて
クラスBlog(models.Model)。
    名前 = models.CharField(max_length=100)
    タグライン = models.TextField()
    def __unicode__(self):
        return self.name
class Author(models.Model):
    名前 = models.CharField(max_length=50)
    email = models.EmailField()
    def __unicode__(self):
        return self.name
class Entry(models.Model):
    blog = models.ForeignKey(ブログ)
    ヘッドライン = models.CharField(max_length=255)
    body_text = models.TextField()
    pub_date = models.DateTimeField()
    authors = models.ManyToManyField(Author)です。
    def __unicode__(self):
        return self.headline
これはblog、author、entryを持つモデルです。entryはそれぞれblogテーブルとauthorテーブルにリンクされ、entryは外部キーによってblogテーブルにリンクされています(modles. authorは多対多の関係で、modlesによって実現されています)。 
I. 挿入 データベース をsave()メソッドで実行すると、以下のようになります。 
>>> from mysite.blog.models import Blog 
>>> b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.') 
>>> b.save()
II. 更新 データベース を実装していますが、これもsave()メソッドで以下のように実装しています。 
>> b5.name = '新しい名前' です。 
>> b5.save()




次の例のように、外部キーや多対多の関係を保持するフィールドを指定します。 
外部キーフィールドの更新は、オブジェクトの種類を正しく指定すれば、通常のフィールドと同じように行うことができます。 
>>> cheese_blog = Blog.objects.get (name="Cheddar Talk") 
>>> entry.blog = cheese_blog 
>>> entry.save()
多対多のフィールドの更新は少し異なり、add() メソッドを使用して関連するフィールドの値を追加します。 
>> joe = Author.objects.create(name="Joe")です。 
>> entry.authors.add(joe)を追加します。
III. オブジェクトを取得する
>>> Blog.objects 
< django .db.models.manager.Manager object at ... > 
>>> b = Blog(name='Foo', tagline='Bar') 
>>> b.objects 
トレースバック 
    ... 
AttributeError: "マネージャーはブログインスタンスからアクセスできません。
1. 全オブジェクトの取得
>>> all_entries = Entry.objects.all()
all() メソッドを使用すると データベース データベース内のすべてのオブジェクト。
2. 特定のオブジェクトを取得する 
次の2つのメソッドを使用します。 
fileter(**kwargs) 
引数に等しい(=)QuerySetを返します。 
exclude(**kwargs) 
引数で指定した(! =)にマッチしないQuerySetを返します。
Entry.objects.filter (pub_date__year=2006) 
Entry.objects.all().filter (pub_date__year=2006) は動作しません。all() はすべてのオブジェクトを再度取得するときに使用するのが最適ですが、動作しません。 
上の例は、同等のsql文です。 
slect * from entry where pub_date_year='2006'
リンクフィルターです。 
>>> Entry.objects.filter(エントリ.オブジェクト.フィルタ)( 
... headline__startswith='What' 
... ).exclude( 
... pub_date__gte=datetime.now() 
... ).filter ( 
... pub_date__gte=datetime(2005, 1, 1) 
... )
最後に返されたQuerySetは、'What%'とput_date<now()とpub_date>2005-01-01といったヘッドラインです。
別のアプローチ 
>> q1 = Entry.objects.filter (headline__startswith="What") 
>> q2 = q1.exclude(pub_date__gte=datetime.now()) 
>> q3 = q1.filter (pub_date__gte=datetime.now()) 
この方法の利点は、q1が再利用できることである。
QuerySetは遅延ロード 
使用時のみアクセス データベース を以下のように設定します。 
>>> q = Entry.objects.filter (headline__startswith="何")です。 
>>> q = q.filter (pub_date__lte=datetime.now()) 
>>> q = q.exclude(body_text__icontains="食品")です。 
>>> print q 
print qのときだけアクセス データベース .
その他のQuerySetメソッド 
>>> Entry.objects.all()[:5]. 
これは、最初の5つのエントリーテーブルのデータを探しています。
>>> Entry.objects.all()[5:10]を実行します。 
これは5日から10日の間のデータを探しています。
>>> Entry.objects.all()[:10:2] を実行します。 
これは、0番目から10番目までを2刻みで開始するクエリです。
>>> Entry.objects.order_by('headline')[0]. 
これは、見出しフィールドでソートした後に取得される最初のオブジェクトです。
>>> Entry.objects.order_by('ヘッドライン')[0:1].get()です。 
上記と同等です。
>>> Entry.objects.filter (pub_date__lte='2006-01-01') 
SELECT * FROM blog_entry WHERE pub_date <= '2006-01-01' と同じです。
>>> Entry.objects.get (headline__exact="Man bites dog")です。 
は、SELECT ... WHERE headline = 'Man bites dog' と同じ意味です。
>>> Blog.objects.get (id__exact=14) # 明示的なフォーム 
>>> Blog.objects.get (id=14) # __exact は暗黙の了解です。 
これら2つのアプローチは、どちらもid=14のオブジェクトを探すという点で等価です。
>>> Blog.objects.get (name__iexact="beatles blog")。 
name="beatles blog"で、大文字小文字を区別しないオブジェクトを検索します。
Entry.objects.get (headline__contains='Lennon') 
SELECT ... WHERE headline LIKE '%Lennon%' と同じです。
startswithは、SQL文の'Lennon%'のような名前と同じです。 
endswithはSQL文の'%Lennon'のような名前と同じです。




>>> Entry.objects.filter (blog__name__exact='Beatles Blog') 
Entryテーブルで外部キー関係blog_name='Beatles Blog'を持つEntryオブジェクトを検索します。
>>> Blog.objects.filter (entry__headline__contains='Lennon') 
ブログテーブルの外部キー関係entryテーブルのヘッドラインフィールドにLennonを含むブログデータを検索する。
Blog.objects.filter (entry__author__name='Lennon')を使用します。 
blogテーブルの外部キー関係entryテーブルのauthorフィールドにあるLennonのブログデータを検索します。
Blog.objects.filter (entry__author__name__isnull=True)です。 
Blog.objects.filter (entry__author__isnull=False,entry__author__name__isnull=True)です。 
author_nameの値がNULLの場合のクエリです。
Blog.objects.filter (entry__headline__contains='Lennon',entry__pub_date__year=2008) 
Blog.objects.filter (entry__headline__contains='Lennon').filter ( entry__pub_date__year=2008) 
この2つのクエリは、同じ場合もあれば異なる場合もあります。最初のものはすべてのブログデータを制限していますが、2番目のケースでは最初のフィルタが
はブログを制限するもので、エントリーを制限する2番目のフィルターは
>>> Blog.objects.get (id__exact=14) # 明示的なフォーム 
>>> Blog.objects.get (id=14) # __exact は暗黙の了解です。 
>>> Blog.objects.get (pk=14) # pkはid__exactを意味します。 
select * from where id=14 と同じ意味です。




# id 1, 4, 7 のブログエントリーを取得する 
>>> Blog.objects.filter (pk__in=[1,4,7])を使用します。 
select * from where id in{1,4,7} と同じ意味です。 
# idが> 14のブログエントリーをすべて取得する 
>>> Blog.objects.filter (pk__gt=14) 
select * from id>14と等価です。
>>> Entry.objects.filter (blog__id__exact=3) # 明示的なフォーム 
>>> Entry.objects.filter (blog__id=3) # __exact は暗黙の了解です。 
>>> Entry.objects.filter (blog__pk=3) # __pk は __id__exact を意味します。 
この3つのケースは同じです




>>> Entry.objects.filter (headline__contains='%') 
は、SELECT ... WHERE headline LIKE '%%%' と同じです。




キャッシュとクエリセット
>>> print [e.headline for e in Entry.objects.all()]. 
>>> print [e.pub_date for e in Entry.objects.all()]. 
と書き換える必要があります。 
>> queryset = Poll.objects.all() 
>>> print [p.headline for p in queryset] # クエリセットを評価する。 
>>> print [p.pub_date for p in queryset] # 評価で得たキャッシュを再利用します。 
キャッシュはこのように使ってアクセス数を減らす データベース データベースの
IV. Qオブジェクトを使った複雑なクエリの実装
Q(question__startswith='Who')|Q(question__startswith='What')です。 
WHERE question LIKE 'Who%' OR question LIKE 'What%'に相当するものです。




Poll.objects.get ( 
    Q(question__startswith='Who')です。 
    Q(pub_date=date(2005, 5, 2))|Q(pub_date=date(2005、5、6))です。 
SELECT * from polls WHERE question LIKE 'Who%' AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06') と同じ意味です。
Poll.objects.get ( 
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))です。 
    question__startswith='誰') 
Poll.objects.get (question__startswith='Who', Q(pub_date=date(2005, 5, 2))) と同じです。| Q(pub_date=date(2005, 5, 6)))




V. オブジェクトの比較
>>> some_entry == other_entry 
>>> some_entry.id == other_entry.id




VI. 削除
Entry.objects.filter (pub_date__year=2005).delete()




b = Blog.objects.get(pk=1)です。 
# これはBlogとそのEntryオブジェクトを全て削除します。 
b.delete()
Entry.objects.all().delete()を実行します。 
すべて削除
VII. 複数の値を一度に更新する
# pub_dateが2007年の全てのヘッドラインを更新します。 
Entry.objects.filter (pub_date__year=2007).update(headline='Everything is the same')
>>> b = Blog.objects.get (pk=1) 
# すべてのエントリーをこのBlogに属するように変更する。 
>>> Entry.objects.all().update(blog=b)を実行します。
save()メソッドを使用する場合は、以下のように1つずつ保存して、インラインでトラバースする必要があります。 
for item in my_queryset: 
    item.save()
関連するオブジェクト
一対多 
>>> e = Entry.objects.get (id=2) 
>>> e.blog # 関連するBlogオブジェクトを返します。




>>> e = Entry.objects.get (id=2) 
>>> e.blog = some_blog 
>>> e.save()を実行します。
>>> e = Entry.objects.get (id=2) 
>>> e.blog = なし 
>>> e.save() # "UPDATE blog_entry SET blog_id = NULL ...;"
>>> e = Entry.objects.get (id=2) 
>>> print e.blog # データベースをヒットして、関連するBlogを取得します。 
>>> print e.blog # データベースをヒットせず、キャッシュされたバージョンを使用します。
>>> e = Entry.objects.select_related().get(id=2)。 
>>> print e.blog # データベースにヒットせず、キャッシュされたバージョンを使用します。 
>>> print e.blog # データベースにヒットせず、キャッシュされたバージョンを使用する
>>> b = Blog.objects.get (id=1) 
>>> b.entry_set.all() # Blogに関連する全てのEntryオブジェクトを返します。
# b.entry_set はQuerySetsを返すManagerです。 
>>> b.entry_set.filter (headline__contains='Lennon') 
>>> b.entry_set.count()を実行します。




>>> b = Blog.objects.get (id=1) 
>>> b.entries.all() # Blogに関連する全てのEntryオブジェクトを返します。 
# b.entries は QuerySets を返す Manager です。