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

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

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

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

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

1回答

805閲覧

Djangoを使用したDBからのデータの取得について

noname0001

総合スコア16

Django

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

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2019/04/12 06:55

前提・実現したいこと

CSV出力のため、複数テーブルから取得した値を結合するか、もしくは1つのテーブルに関連づいているテーブルのフィールド全てを取得したいです。
下記のモデルの場合に、まずReportテーブルのIDを取得し、関連のDatetimeテーブルから外部キー以外の値(time1,time2)も取得する、もしくは同じIDで一致する行をテーブルごとに取得し、結合するでも良いのです。

models

1class Report(models.Model): 2 3 def __str__(self): 4 return self.id 5 6 id = models.CharField(max_length=32, primary_key=True) 7 foo = models.CharField(max_length=255) 8 9class Datetime(models.Model): 10 11 def __str__(self): 12 return self.time1 13 14 id = models.OneToOneField(Report, on_delete=models.CASCADE) 15 time1 = models.DateTimeField() 16 time2 = models.DateTimeField()

試したこと

queryset_report = Report.objects.filter(datetime__time1__range=(delete_start_date, delete_end_date)).select_related('datetime').select_related('participant')

delete_start_date=2019-01-01 00:00:00
delete_end_date=2019-02-01 00:00:00

発生している問題

print(f'queryset_report.query: {queryset_report.query}') > queryset_report.query: SELECT `report`.`id`, `datetime`.`id`, `datetime`.`time1`, `datetime`.`time2`, FROM `report` INNER JOIN `datetime` ON (`report`.`id` = `datetime`.`id`) WHERE `datetime`.`time1` BETWEEN 2019-01-01 00:00:00 AND 2019-02-01 00:00:00
print(f'queryset_report: {queryset_report.model._meta.fields}') > queryset_report.model._meta.fields: (<django.db.models.fields.CharField: id>)

SELECT文にはdatetime.time1, datetime.time2が含まれており、datetimeテーブルもJOINされているのに対し、fields、values()などで確認するとdatetimeテーブルの情報は一切含まれていません。
なぜでしょう。
どのように取得すべきでしょうか。

よろしくお願い致します。

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

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

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

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

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

guest

回答1

0

ベストアンサー

Python と Django のバージョンを書かれていませんが、 Python 3.7 、 Django 2.2 と仮定して以下回答します。

datetimeテーブルもJOINされているのに対し、fields、values()などで確認するとdatetimeテーブルの情報は一切含まれていません。
なぜでしょう。
どのように取得すべきでしょうか。

ここで fields というのが何なのかよくわかりませんが、 values() については、対象のフィールドを明示的に指定されていないからではないでしょうか。次のような感じでフィールドを明示的に指定すると取得できるものと思います。

python

1values = Report.objects.select_related('datetime').values('datetime__time1', 'datetime__time2')

このあたりのところは公式ドキュメントで詳しく説明されているので、一度ご覧になってみてください。

ちなみに、どうしても values() を使わなくてはいけない強い理由等がなければ、次のような感じで、そのままフィールドを辿って取得する形にした方がシンプルでよいのかなという気がします。

text

1{% for row in queryset_report %} 2 <div> 3 <div>id: {{ row.id }}</div> 4 <div>time1: {{ row.datetime.time1 }}</div> 5 <div>time2: {{ row.datetime.time2 }}</div> 6 ... 7 </div> 8{% endfor %}

もうひとつちなみに、 values() は使うけれど、せめて戻り値の dict のキーはわかりづらい dastetime__time1 等ではなくシンプルな time1 等にしたいという場合には、 django.db.models.Fannotate() 等を使ってエイリアスを作るとよいかと思います。

投稿2019/04/12 13:54

編集2019/04/12 13:55
gh640

総合スコア1407

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

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

noname0001

2019/04/13 15:41 編集

``` queryset_report_values = Report.objects.filter(datetime__time1__range=(delete_start_date, delete_end_date)).select_related('datetime').select_related('participant').values('datetime') ``` 上記を実行してみましたが、結果は、 ``` print(f'queryset_report_values: {queryset_report_values}') > queryset_report_values: <QuerySet [{'datetime': 1}]> ``` となり、 ``` queryset_report = Report.objects.filter(datetime__plan_start_datetime__range=(delete_start_date, delete_end_date)).select_related('datetime').select_related('participant') print(f'queryset_report: {queryset_report}') queryset_report: <QuerySet [<Report: 1>]> ``` の結果と少し異なる形式で表示されました。 また、queryset_report.values()とqueryset_report_values.values()は全く同じ内容で、どちらもReportの情報が入っているだけです。 queryset_reportにはReportの、queryset_report_valuesにはDatetimeの情報が入っているように取得したいのですが、何か方法はありますでしょうか。 Python3.7、Django2.2です。 使うメソッドやライブラリに特に指定はありません。 その他、ご提案いただきましたものに関しましては、参考にさせていただきます。 ありがとうございます。
gh640

2019/04/14 03:02

> ...の結果と少し異なる形式で表示されました。 私の説明がうまく伝わっていない感じがします。私が回答欄に書いた次のパターンはお試しになりましたか? ```python values = Report.objects.select_related('datetime').values('datetime__time1', 'datetime__time2') ``` `values()` の引数に注目してください。「上記を実行してみましたが」と言われているコードとは大きく異なるところがあるのですが、お気づきになるでしょうか。 念のために申し上げると、ここで `filter()` は今回の問題の本質とは関係がないと思います。 `filter()` は `values()` の出力の構成に影響しないので、 `filter()` を外した形で確認してみてください。 > queryset_reportにはReportの、queryset_report_valuesにはDatetimeの情報が入っているように取得したいのですが、何か方法はありますでしょうか。 ?? 新たな質問でしょうか? `values()` の使い方を理解されたら、そのあたりも自然と理解できるのではないかと思いますがいかがでしょう。 その感じですと、回答であげたリンク先(公式ドキュメント)はまだご覧になっていない感じ、です、かね。そのままずばりな答えが書かれていますので、ご覧になってみてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問