2016-05-26 13 views
0

これは達成しようとしているものの単純化された例です。Django - ランダムなdbエントリからの動的フォームの作成

class Question(models.Model): 
    text = models.CharField(max_length=255) 

class Answer(models.Model): 
    text = models.CharField(max_length=255) 
    question = models.ForeignKey(Question) 

との私は、データベース内の質問の数千を持っているが、私は、各ユーザーが唯一のいくつかのランダムなものをお答えしたいとしましょう:のは、私はこれらの二つのモデルを持っているとしましょう。だから、私の考えは動的なフォームを作成することでした。このような何か:

class QuestionnaireForm(forms.Form): 
    def __init__(self, *args, **kwargs): 
     super(QuestionnaireForm, self).__init__(*args, **kwargs) 

     questions = list(Question.objects.all()) 
     random.shuffle(questions) # it successfully validates without this line 
     questions = questions[:3] 

     for q in questions: 
      self.fields[q.text] = forms.CharField() 

私はこれを行うと、必要に応じて、私は私の3つのランダムな質問を受けるが、フォームが検証されません。シャッフルをコメントアウトすると、すべてうまく動作しますが、毎回同じ質問が表示されます。

私は、Djangoがフォーム提出時に再度__init__メソッドを呼び出しているので、シャッフルを繰り返してさまざまな質問をしているようです。私はドキュメンテーションを読んでみましたが、私はなぜそれがそうであるのかについて私の頭を包み込むことはできません。

+0

もちろん、提出時にinitを呼び出します。それがあなたの見解です。 –

答えて

1

Random ordering

questions = Question.objects.filter(pk__in=request.POST.getlist('ids')) 

と形成するためにそれを置く:

questions = Question.objects.all().order_by('?')[:3] 

フォームを検証するために、それはあなたのようなものと同じクエリセットを復元する必要がある、ヒンク。あなたは同じ注文を保存する必要があると思う - あなたはフォームでこのリストを並べ替えることができます。

更新:

あなたが要求間でいくつかの方法を状態を保存する必要があります。隠しフィールドを追加したり、URLパラメータを追加したり、Cookieを設定したり、ユーザーのプロファイルに情報を保存したりすることができます。 Tipical方法は隠し入力を設定されています(一般的にはデフォルトのdjango ModelFormの動作です)。

最初のリクエストでは、フォームを表示するときにクエリーセットを取得して、たとえばpkでソートし、フォームに入れてIDのある非表示フィールドを追加します。ユーザーが応答付きでPOSTリクエストをしたとき - このIDでクエリセットを復元し、同じ方法でもう一度ソートし、フォームに入れて検証します。

+0

ランダムな注文についてだけでなく、フォームが投稿されたときに再び同じ質問が表示されます。このアプローチでは、GETリクエストとPOSTリクエストで異なる質問が生成されます。 – AKS

+0

Nope。問題は残っている。私は効率のために_random.shuffle_を使いましたが、基本的に同じことをしています。 –

+0

私は答えを更新しました。 – qnub

関連する問題