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

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

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

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

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

Python

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

Q&A

解決済

2回答

526閲覧

質問投稿サイトのベストアンサーを扱うデータベースの仕組み

退会済みユーザー

退会済みユーザー

総合スコア0

Django

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

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

Python

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

0グッド

2クリップ

投稿2018/04/16 00:40

Djangoで質問投稿サイト(teratailのようなもの)を作っています。
質問に対する複数の回答のうち、一つをベストアンサーにしたいと思います。
その場合のデータベースをどのようにしようかと悩んでいます。

現状のmodels.pyは添付のとおりです。
ベストアンサーに選ばれたかどうかは、class Answerのbest_answarがTrueかFalseかで
判定しています。

python

1# models.py 2# 質問を扱うモデル 3class Question(models.Model): 4 content = models.TextField() # 質問内容 5  … 6 datetime = models.DateTimeField(auto_now=True) # 投稿時間 7 8# 回答を扱うモデル 9class Answer(models.Model): 10 question = models.ForeignKey(Question, on_delete=models.CASCADE) 11  best_answer = models.BooleanField(default=False) 12  … 13 datetime = models.DateTimeField(auto_now=True) 14

しかし、これだと、複数の回答をベストアンサーにすることができてしまいます。
一方で、class Questionにbest_answer = models.ForeignKey(Answer, on_delete=models.CASCADE)という形でもたせると、ベストアンサーを選ぶときに、Questionのdatetimeも更新されてしまいます。
どうしたら、Question1つに対してベストアンサー1つとしつつ、ベストアンサーを選ぶときにQuestionのdatetimeを変更しないようにできるでしょうか。
お分かりの方、ご教示頂ければ幸いです。
よろしくお願い致します。

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

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

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

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

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

guest

回答2

0

ベストアンサー

方法は幾らでもあるとは思います。

基本は「ベストアンサーを選ぶときは必ずベストアンサーしか更新しない」ですね。
いずれの場合も本体の更新日付を関わらせないようにする必要があります。

  • 質問データにベストアンサー回答IDを保管する場所とベストアンサー用のdatetimeを持っておく方法

 →ベストアンサーを更新するときは質問データの更新日付を更新しない
→質問データ取得時にベストアンサー回答IDを持っているので楽なのは楽

  • 回答データにベストアンサーフラグとベストアンサー用のdatetimeを持っておく方法

 →ベストアンサーを更新するときは回答データの更新日付を更新しない
→回答データを質問IDとベストアンサーフラグonで検索してヒットしない場合のみベストアンサー選べるように

  • ベストアンサーテーブルを持つ。(キー:質問ID,ベストアンサー回答ID)

 →これが一番簡単かも。質問IDで検索してヒットしない場合のみベストアンサー選べるように

投稿2018/04/16 00:50

m.ts10806

総合スコア80765

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

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

退会済みユーザー

退会済みユーザー

2018/04/17 04:38

複数の方法をご提示いただき、ありがとうございます。 ベストアンサーテーブルを別途作る案で、実装しました。 一つしかベストアンサーに登録できないということを、モデルで実装しようという思い込みがあったのですが、冷静に考えたら、既にベストアンサーが登録されている場合は、それ以上登録させないようにviews.pyで実装すればよいということですね。
m.ts10806

2018/04/17 04:40

そうですね。 色々無理やり一緒にするより、役割をわけて考えた方がわかりやすくなると思います。 1つのテーブルでやりきろうとして破綻(もしくは拡張性が損なわれる)するパターンは幾つも見てきました。 結局分けた方がつながりが緩く、付け外しが簡単で、且つ、構造的にも関係性を維持しやすくなります。
退会済みユーザー

退会済みユーザー

2018/04/17 04:42

私も1つのテーブルに色々盛り込もうとしてしまう傾向がありますが、今回の件で、緩いつながりのメリットを実感しました。
m.ts10806

2018/04/17 04:46 編集

私も以前ナレッジを作ってて タグとかサブコンテンツとか色々管理したい情報があったのですが一緒にすると無理がくるので別々にして、必要に応じてつなげるようにしたところ結構楽だった(しかも不要な情報を取得しないので軽くて早い)ので、その経験が活きたようで、良かったです。
guest

0

投稿時間が更新されるのが問題なわけですよね。
ちょっと調べた感じですいませんが、

datetime = models.DateTimeField(auto_now_add=True) # 投稿時間

にすればいける気がします。

https://www.ianlewis.org/jp/django-datetimefield-auto_now-auto_now_add
https://qiita.com/kasajei/items/7ea3d507aa334627ad1c

ただ、mts10806さんの最後の関連テーブル案はいけてると思います。

投稿2018/04/16 01:51

szk.

総合スコア1400

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

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

退会済みユーザー

退会済みユーザー

2018/04/17 04:40

ご回答頂き、ありがとうございます。 DateTimeFieldだけ更新しない方法があるのですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問