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

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

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

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

Python 3.x

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

Q&A

解決済

1回答

1005閲覧

【Django models.py】テーブルを紐づけし、一連のデータを取得・各々のテーブルで更新できるようにしたい

退会済みユーザー

退会済みユーザー

総合スコア0

Django

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

Python 3.x

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

0グッド

0クリップ

投稿2021/05/19 04:49

編集2021/05/19 06:57

前提・実現したいこと

models.pyにて、「名前」と「住所」と「趣味」のクラスを作成したとします。

そのとき、各々で新規作成・更新・削除ができるようにし、
かつ後に検索あるいはcsvなどで出力する際、それらの情報がまとめて入手できるようにするには、
どうしたらよいでしょうか?

【具体的な例】

名前住所趣味
田中北海道テニス
佐藤新潟サッカー
斎藤大分野球

上記のようなデータがあったとき、例えば「斎藤」の情報を削除します。
このとき、「斎藤」というデータは消えてよいのですが、
「大分」「野球」という情報は削除したくありません。(次に流用できるため)

また、データを取得する際、
田中の場合、
名前:田中
住所:北海道
趣味:テニス
のように紐づけされた情報を取得できる状態にしたいです。

発生している問題・エラーメッセージ

住所を主キーとして設定した際、エラーメッセージが出ました。
python manage.py shell

TypeError: __str__ returned non-string (type Person)

該当のソースコード

python

1# models.py 2 3from django.db import models 4 5 6 7class Address(models.Model): 8 9 prefectures = models.CharField(max_length=20, verbose_name="都道府県") 10 11 def __str__(self): 12 return self.prefectures 13 14 class Meta: 15 verbose_name = "住所" 16 17 18 19class Person(models.Model): 20 21 name = models.CharField(max_length=20, verbose_name="名前") 22 23 address = models.ForeignKey(Address, on_delete=models.CACADE) 24 25 def __str__(self): 26 return self.name 27 28 class Meta: 29 verbose_name = "個人情報" 30 31 32 33class Hobby(models.Model): 34 35 p_hobby = models.CharField(max_length=20, verbose_name="趣味") 36 37 person = models.ForeignKey(Person, on_delete=models.CACADE) 38 39 def __str__(self): 40 return self.p_hobby 41 42 class Meta: 43 verbose_name = "趣味" 44 45 46

試したこと

上記のように、参照先以外の残り2つのclassに対して、
ForeignKeyの記述を行いましたが、エラーが出ました。

また、そもそもこの記述だと、Personの情報を削除した後、Hobbyの情報も削除されてしまうことに今気づきました。

補足情報(FW/ツールのバージョンなど)

Django 3.2.3

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

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

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

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

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

guest

回答1

0

ベストアンサー

住所、趣味を残すという部分(外部キー)でございますが、
もし、NULLへの置き換えでもよければSET NULLなどで実現できるかと思います。
(CACADE -> CASCADE の部分は単なるtyponでしょうか?)

DBから引っ張ってくる場合は必ずHobbyが存在するのであれば、Hobbyを引っ張ることで
芋づる式に全て取ることが可能でございます。(後続で何か処理する場合はselect_related使った方が良いです。)

もしそれぞれの項目で歯抜け存在してしまう場合は、それぞれのModelを面倒ではありますが、
引っ張ってくるのが良いかなと思います。
DBのアクセス等は下記記事が参考になるかと思います。
https://developer.yukimonkey.com/article/20200417/

投稿2021/05/29 21:34

m2l

総合スコア318

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

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

退会済みユーザー

退会済みユーザー

2021/05/31 06:56

回答ありがとうございます。 おかげで解決しました。 今回modelで定義したところにも修正が必要でした。 以下修正内容です。 それぞれに対しリレーションを行う際、「1対多」を利用していましたが、 これらは「多対多」の関係でないといけないこと。 また、PersonとAddress / HobbyとPersonを紐づける考えまではよかったですが、 リレーションの記載(今回はManyToManyFieldを記載するところ)は、Personにまとめる必要があったこと。 つまり、 class Person(models.Model): 以下に address = hobby = と記述する必要があった。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問