はじめに
Djangoのこちらの公式ドキュメントから、テーブル・モデルを作成後にモデル内のデータ取得、及びモデル間でデータを参照する方法をまとめていきます。
テーブル・モデル
出版社(SyuppanSya)、著者(Tyosya)、本(Hon)のテーブルが存在することを想定して考えていきます。
モデル間の関係は、以下の通りです。
本と出版社の関係は、多対一。 Hon(多) --> (一)SyuppanSya
本と著者の関係は、多対対。Hon(多) --> (多)Tyosya
テーブル・モデル・コード
実際のデータ・モデルのコードは以下の通りです。
from django.db import models
class SyuppanSya(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def __str__(self):
return self.name
class Tyosya(models.Model):
name = models.CharField(max_length=200)
email = models.EmailField()
def __str__(self):
return self.name
class Hon(models.Model):
syuppan = models.ForeignKey(SyuppanSya, on_delete=models.CASCADE)
title = models.CharField(max_length=255)
body_text = models.TextField()
pub_date = models.DateField()
mod_date = models.DateField()
authors = models.ManyToManyField(Author)
number_of_comments = models.IntegerField()
number_of_pingbacks = models.IntegerField()
rating = models.IntegerField()
def __str__(self):
return self.title
テーブルデータの取得
-
本テーブルに入っている全件を取得します。
Hon.objects.all()
-
本テーブルに入っている中で、本の題名が「噂のドラえもん」になっているものを取得します。
Hon.objects.filter(title="噂のドラえもん")
-
本テーブルに入っている中で、本の題名に「Theドラえもん」を含んでいるもの(大文字・小文字の区別あり)を取得します。
Hon.objects.filter(title__contains="Theドラえもん")
-
本テーブルに入っている中で、本の題名に「Theドラえもん」を含んでいるもの(大文字・小文字の区別なし)を取得します。
Hon.objects.filter(title__icontains="Theドラえもん")
-
本テーブルに入っている中で、本の題名が「Theドラえもん」で始まるもの(大文字・小文字の区別あり)を取得します。
Hon.objects.filter(title__startswith="ドラえもん")
-
本テーブルに入っている中で、本の題名が「Theドラえもん」で始まるもの(大文字・小文字の区別なし)を取得します。
Hon.objects.filter(title__istartswith="ドラえもん")
-
本テーブルに入っている中で、本の題名が「Theドラえもん」で終わるもの(大文字・小文字の区別あり)を取得します。
Hon.objects.filter(title__endswith="ドラえもん")
-
本テーブルに入っている中で、本の題名が「Theドラえもん」で終わるもの(大文字・小文字の区別なし)を取得します。
Hon.objects.filter(title__iendswith="ドラえもん")
-
本テーブルに入っている内で、出版年が2006年のものを取得します。
Hon.objects.filter(pub_date__year=2006)
テーブル間の参照方法
-
本テーブルから、出版社テーブル内の出版社名(name)を参照(順参照)。
Hon.objects.filter(syuppan__name='Syppannsya_Syamei')
-
出版社テーブルから、本テーブル内のタイトル(title)が「ドラえもん」であるものを参照(逆参照)。
SyuppanSya.objects.filter(hon__title='ドラえもん')
-
出版社テーブルから、本テーブル内のタイトル(title)に「ドラえもん」を含むものを参照(逆参照)。
SyuppanSya.objects.filter(hon__title__contains='ドラえもん')
-
出版社テーブルのidが1であるデータから、本テーブル内のデータを逆参照する。
b = SyuppanSya.objects.get(id=1) b.hon_set.all()
-
出版社テーブルのidが1であるデータから、本テーブル内のデータでタイトル(title)に「ドラえもん」を含むものを逆参照する。
b = SyuppanSya.objects.get(id=1) b.hon_set.filter(title__contains='ドラえもん')
その他
-
本テーブル内から、コメント数(number_of_comments)のほうがリンク数(number_of_pingbacks)よりも多いものを取得する。
from django.db.models import F Entry.objects.filter(number_of_comments__gt=F('number_of_pingbacks'))
-
DBへのSQL発行回数(クエリ回数)について(悪い例)
下記では、本テーブルの内容が2回呼び出されており、DBへのアクセスが結果として増えている。print([h.title for h in Hon.objects.all()]) print([h.pub_date for h in Hon.objects.all()])
-
DBへのSQL発行回数(クエリ回数)について(良い例)
下記では、本テーブルの内容を呼び出す回数が上記のコードに比べ1回に減った。queryset = title.objects.all() print([h.title for h in Hon.objects.all()]) print([h.pub_date for h in Hon.objects.all()])
参考
https://docs.djangoproject.com/en/3.1/topics/db/queries/
https://docs.djangoproject.com/en/3.1/ref/models/querysets/