質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2482閲覧

DjangoのForeignKeyはどうやってjoinしていますか?

sususu

総合スコア99

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/08/14 23:44

編集2019/08/15 01:09

ptyhon,Djangoの初心者です。
表題の件の通りどういった条件でjoinしているのかわかりません。
どなたか教えていただけると幸いです。

下記のサイトを参考に学習しています。
https://djangobrothers.com/tutorials/photo_app/foreignkey/

コードは下記の通りです。

from django.db import models from django.contrib.auth.models import User class Category(models.Model): title = models.CharField(max_length=20) def __str__(self): return self.title class Photo(models.Model): title = models.CharField(max_length=150) comment = models.TextField(blank=True) image = models.ImageField(upload_to = 'photos')   category = models.ForeignKey(Category, on_delete=models.PROTECT)#ForeignKey user = models.ForeignKey(User, on_delete=models.CASCADE)#ForeignKey created_at = models.DateTimeField(auto_now=True) def __str__(self): return self.title

Category,User,Photoのテーブルがそれぞれあり、
『1』対『多』の『多』の方に外部キーを持たせると書籍にありました。
上記の場合Photoのクラスに『ForeignKey』を持たせ、ForeignKeyの第一引数に
結合したいテーブル名を記載するという認識です。

Join User またはJoin Category は Foreignkey(User,...) や Foreignkey(Category,...)
にあたると認識しているのですが、join文で言う 『... ON ????』の????にあたるキーはどこで指定しているのでしょうか。

結合するテーブルを指定した後、どのような条件でjoinしているのかわかりません。
onに代わる記述がどこかにあればイメージがわくのかもしれませんが...

どなたかご回答いただけると助かります。
よろしくお願いいたします。

※追記
例えばですが『ForeignKey 外部キー』で検索すると下記のサイトなど出てきますが。
https://qiita.com/SLEAZOIDS/items/d6fb9c2d131c3fdd1387

FOREIGN KEY (department_id)・・・どのカラムにキーを制約つけるのか(参照元) REFERENCES departments (department_id)・・・どのテーブルのどのカラムを参照するか

などカラムの参照条件があります。
djangoの場合この条件をどこで設定しているのでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

select_relatedprefetch_relatedがあり、それらを使ってjoinができるようになり、想定していないクエリーの発行を止めることができます。

https://docs.djangoproject.com/en/2.2/ref/models/querysets/#select-related

select_relatedについて

python

1photo = Photo.objects.select_related('user', 'category').get(id=1) 2photo.user # joinし、データが既に取得されているのでSQLは発行されない 3photo.category # joinし、データが既に取得されているのでSQLは発行されない

prefetch_relatedについて

usercategoryからPhotoを取る場合は下記のような記述になるはずです。

python

1user = User.objects.prefetch_related('photo_set').get(id=1) 2user.photo_set.all() # ユーザーに紐づく`photo`が取得できる。

related_nameについて

related_nameを使うと_setと記述しないで良いので定義すると良いかもです。参考までにどうぞ。

diff

1class Photo(models.Model): 2 title = models.CharField(max_length=150) 3 comment = models.TextField(blank=True) 4 image = models.ImageField(upload_to = 'photos') 5+  category = models.ForeignKey(Category, on_delete=models.PROTECT, related_name='photos') 6+ user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='photos') 7 created_at = models.DateTimeField(auto_now=True) 8

python

1user = User.objects.prefetch_related('photos').get(id=1) 2category = Category.objects.prefetch_related('photos').get(id=1) 3 4user.photos.all()

投稿2019/08/15 00:27

shotanuki

総合スコア102

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sususu

2019/08/15 00:53

ご回答ありがとうございます。 select_relatedがphotoから特定できるuserの単数の値を参照でき、 prefetch_relatedがuserから特定できるphotoの複数の値を参照できるのがわかりました。 しかしonするためのキーの値はどれにあたるのかまだ理解できておりません。 申し訳ございませんがよろしくお願いします。
shotanuki

2019/08/15 01:17

photoで定義している外部キーがキーの値になっています。userやcategoryはphotoテーブルではそれぞれ user_idと category_idとなっています。 イメージとしては下記のようになります。 select * from photo P join user U on U.id=P.user_id where P.id=1 Photo.objects.filter().select_related('user').query 上記で発行されるQueryが見えるので確認すると良いかもです。
sususu

2019/08/15 01:46

ありがとうございます。 イメージとしてPhotoテーブルのcategoryカラムにcategoryテーブルのプライマリーキー(id)が入っているという認識でよかったでしょうか。
shotanuki

2019/08/15 01:47

はい、その認識で正しいです。
sususu

2019/08/15 01:50

ありがとうございます。 ORMを今回初めて使用したので理解に苦しんでおります。 とても助かりました。ベストアンサーにさせて頂きます。
shotanuki

2019/08/15 01:55

よかったです!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問