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

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

ただいまの
回答率

90.51%

  • Python

    8047questions

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

  • Django

    1062questions

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

  • データベース設計

    145questions

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

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

解決済

回答 2

投稿

  • 評価
  • クリップ 2
  • VIEW 330

mulberryfields

score 752

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

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

# models.py
# 質問を扱うモデル
class Question(models.Model):
    content = models.TextField() # 質問内容
  …
    datetime = models.DateTimeField(auto_now=True) # 投稿時間

# 回答を扱うモデル
class Answer(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
  best_answer = models.BooleanField(default=False)
  …
    datetime = models.DateTimeField(auto_now=True)

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+7

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

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

  • 質問データにベストアンサー回答IDを保管する場所とベストアンサー用のdatetimeを持っておく方法
    →ベストアンサーを更新するときは質問データの更新日付を更新しない
    →質問データ取得時にベストアンサー回答IDを持っているので楽なのは楽
  • 回答データにベストアンサーフラグとベストアンサー用のdatetimeを持っておく方法
    →ベストアンサーを更新するときは回答データの更新日付を更新しない
    →回答データを質問IDとベストアンサーフラグonで検索してヒットしない場合のみベストアンサー選べるように
  • ベストアンサーテーブルを持つ。(キー:質問ID,ベストアンサー回答ID)
    →これが一番簡単かも。質問IDで検索してヒットしない場合のみベストアンサー選べるように
     

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/04/17 13:38

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

    キャンセル

  • 2018/04/17 13:40

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

    キャンセル

  • 2018/04/17 13:42

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

    キャンセル

  • 2018/04/17 13:46 編集

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

    キャンセル

+2

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

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/17 13:40

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

    キャンセル

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

  • ただいまの回答率 90.51%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Python

    8047questions

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

  • Django

    1062questions

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

  • データベース設計

    145questions

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