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

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

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

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

Python 3.x

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

Q&A

解決済

1回答

7617閲覧

Python Djangoモデルのリレーションについて分かりません。

yuki1010

総合スコア43

Django

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

Python 3.x

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

0グッド

0クリップ

投稿2016/09/26 18:47

Djangoの色々と勉強しているものです。
モデルのリレーションについて質問があります。
ユーザーとイベントカテゴリーとエリアモデルを使い以下のことを行おうとしているのですが上手くいきません。お力なってくれる方がいれば幸いです。

・ユーザーがどのイベントカテゴリーとそれに伴ったエリアに興味があるかを管理できるシステム
・各ユーザーに対してイベントカテゴリー被ってはいけない
・ユーザーとイベントカテゴリーとエリアモデルを管理するためにChooseEventモデルを中間に置きました。

自分が作ったmodels.pyです。

python

1from django.db import models 2# Abstract Modelでupdatedとmodifiedフィールドを共通フィールドに 3from core.models import TimeStampedModel 4from django.contrib.auth.models import User 5 6 7class EventCategory(TimeStampedModel): 8 category_name = models.CharField(max_length=200) 9 10 def __str__(self): 11 return self.category_name 12 13 14class Area(TimeStampedModel): 15 area_name = models.CharField(max_length=200) 16 17 def __str__(self): 18 return self.area_name 19 20 21class ChooseEvent(TimeStampedModel): 22 categories = models.ForeignKey(EventCategory, on_delete=models.CASCADE) 23 area_list = models.ForeignKey(Area, on_delete=models.CASCADE) 24 user = models.ForeignKey(User, on_delete=models.CASCADE) 25 26 def __str__(self): 27 return str(self.user)

このコードですと各ユーザーに必ず1つのイベントカテゴリー名が制御できません。
forms.pyなどで制御するしかないのでしょうか?
どなたかお力添えよろしくお願いします。
それともう一つ質問があります。
ForeignKeyのon_delete=models.CASCADEとはどう云う意味なのでしょうか?

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

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

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

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

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

guest

回答1

0

ベストアンサー

確認です。

ユーザが
・taro
・ziro
・saburo
と存在し、EventCategoryに
・Event1
・Event2
・Event3
とあった場合に、taroがEvent1を選び登録するとziro、saburoがEvent1を選べない、
という動作でしょうか。

その場合でしたら、

python

1user = models.OneToOneField(User, on_delete=models.CASCADE)

のように、categoriesとuserのForeignKeyを、OneToOneFieldにするといかがでしょうか。

ForeignKeyのon_delete=models.CASCADEについてですが、これはForreignKeyとして指定しているオブジェクトが削除された際にどうするか?という挙動になります。
例えば以下のようなモデルあったとして

python

1from django.db import models 2 3 4class Category(models.Model): 5 """カテゴリ""" 6 7 name = models.CharField(max_length=255) 8 9 def __str__(self): 10 return self.name 11 12 13class Post(models.Model): 14 """記事""" 15 16 title = models.CharField(max_length=255) 17 text = models.TextField() 18 category = models.ForeignKey(Category, on_delete=models.CASCADE) 19 20 def __str__(self): 21 return self.title

カテゴリに「食べ物」があったとします。
記事を100記事ほど作り、全て記事のカテゴリは食べ物を指定します。
この後、「食べ物」カテゴリを削除すると、「食べ物」カテゴリを選択した100記事も一緒に削除されてしまいます。これは、on_delete=models.CASCADEの挙動です。(on_deleteのデフォルトはmodels.CASCADE)
このような場合に、
・PROTECT (削除できないように保護する)
・SET_NULL (nullを入れる。null=True、等と指定しておかなくてはいけません)
...
などで挙動が変更できます。


2016/09/27 17:30追記

ご返信ありがとうございます、承知しました。
では、ChooseEventモデルを以下のように変更するといかがですか。
追加したのは、class Metaのunique_togetherです。

python

1class ChooseEvent(TimeStampedModel): 2 categories = models.ForeignKey(EventCategory, on_delete=models.CASCADE) 3 area_list = models.ForeignKey(Area, on_delete=models.CASCADE) 4 user = models.ForeignKey(User, on_delete=models.CASCADE) 5 6 # ここを追加! 7 class Meta: 8 unique_together = ('categories', 'user',) 9 10 def __str__(self): 11 return str(self.user)

これですと、taroがEvent1を一度選び保存すると、次回以降taroはEvent1で新たに保存しようとすると
エラーとなります。

いかがでしょうか。

投稿2016/09/26 22:49

編集2016/09/27 08:41
toritoritorina

総合スコア972

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

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

yuki1010

2016/09/27 05:00

toritoritorina様のご質問で taroがEvent1を選び登録するとziro、saburoがEvent1を選べない、 という動作でしょうか。 とあるのですが、taroがEvent1を選んでもziro、saburoはEvent1を選べます。 taroが再び新規でEvent1を選べなくしたいです。 説明不足で失礼しました。 それとon_deleteと説明もありがとうございます。凄く良く理解することができました!!
yuki1010

2016/09/27 09:59

ありがとうございます。色々と勉強になりました。フォローさせてください。(^^)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問