2011-01-18 11 views
3

私はいくつかのサンプルアプリケーションでdjangoフレームワークを学ぼうとしています。現在、私はフィードバック/調査アプリケーションに取り組んでいます。 それは次のモデルを使用しています:同じビューで複数のフォームを使用する

class Survey(models.Model): 
    title = models.CharField(_(max_length=255) 
    slug = models.SlugField(_(max_length=255, unique=True) 
    description= models.TextField(blank=True) 


class Question(models.Model): 
    survey = models.ForeignKey(Survey, related_name='questions') 
    question = models.TextField() 

class Answer(models.Model): 
    question = models.ForeignKey(Question, related_name='answers') 
    answer = models.TextField() 

基本的に調査が質問に含まれていますし、その答えは、答えに保存されます。

今私が理解していないのは、ビューが呼び出されたときに調査のすべての質問を表示するフォームを作成する方法です。 私はこれはありませんが、私が望むようにフォームを生成しますが、すべての答えから保存されている、ということである

def show_questions(request, slug): 
    survey = get_object_or_404(Survey.objects, slug=slug) 
    forms = forms_for_survey(survey, request) 
    context = { 
     'survey':survey, 
     'forms':forms, 
     } 
    if (request.POST and all(form.is_valid() for form in forms)): 
     for form in forms: 
      form.save() 
     return HttpResponseRedirect(reverse('show_surveys',)) 
    return render_to_response(
     'feedback/show_questions.html', 
     context, 
     context_instance = RequestContext(request) 
     ) 

のようなものである。このため、この

class BaseAnswerForm(Form): 
    answer = None 
    def __init__(self, question,*args, **kwdargs): 
     self.question = question 
     #self.answer = None 
     super(BaseAnswerForm, self).__init__(*args, **kwdargs) 
     answer = self.fields['answer'] 
     answer.label = question.question 

    def save(self, commit=True): 
     ans = self.answer 
     if ans is None: 
      ans = Answer() 
     ans.question = self.question 
     ans.answer = self.cleaned_data['answer'] 
     if commit: ans.save() 
     return ans 

class TextAnswerForm(BaseAnswerForm): 
    answer = CharField() 

def forms_for_survey(survey, request): 
    if request.POST: 
     post = request.POST 
    else: 
     post = None 
    return [TextAnswerForm(q,data=post) 
      for q in survey.questions.all()] 

ビューのようなフォームを作成しようとしました最後の回答フィールド。 私は助けてください、これはformetsを使用して簡単になります、あなたはどのように簡単に実装できるか教えてください。ありがとう

答えて

1

prefix引数繰り返し同じ形式を使用して(フォームセットは、それを使用)、またはフィールド名を衝突していることが起こるのフォームを使用している場合、競合の問題を命名防ぐためにそこにある - 各生成の前に付加される各Formユニークprefixを与えますフィールド名。質問のIDを使用するのが理想的です:

return [TextAnswerForm(q,data=post, prefix='q_%s' % q.pk) 
     for q in survey.questions.all()] 
+0

ありがとう、私はこれがトリックを行うべきだと思います。私はそれを試み、あなたに知らせるでしょう。私が慣れなければならないのは、これらの小さなものです。私は__init__のidを変更することで、ハッキリメソッドを試してみました。しかし、これはよりクールに見える – dushyant88

+0

ありがとう、このソリューションは完璧で簡単に実装することができました – dushyant88

2

おそらく理由は、フォームフィールドの名前が衝突するからです。

あなたはその問題を回避できますが、すでにFormsets Documentationを見ましたか?

formsetは、同じページ上で複数のフォームを使用する抽象化のレイヤーです。

+1

私は手を汚して最終的にフォームセットに飛びつくべきだと思います。ありがとう。 – dushyant88

1

リクエストオブジェクトから取得することはできません。クライアントのWWWページにはいくつのフォームがありますか。
htmlドキュメントに複数のフォームを使用することはできますが、POST/GETデータには送信されたフォームのフィールドのみが含まれている点が異なります。 だから、一つの形で、すべての入力データを配置し、最も簡単な解決策は、いくつかのスペルミスの単語がある場合は、あなたのテンプレートに

<form action="your_viw" method="post"> 
    {% for q in questions %} 
     {{q.question}}<input name="q_{{q.id}}" type="text" /> 
    {% endfor %} 
</form> 

とあなたのビューで

def show_questions(request, slug): 
    survey = get_object_or_404(Survey.objects, slug=slug) 
    context = { 
     'survey':survey, 
     'questions': survey.questions_set, 
     } 
    fields=[(int(name[2:]), val) for name, val in request.POST.items() if name.startswith('q_')] # (question id, answer) list 
    if fields: 
     #validate fields 
     # rest of work... 
    return ... 

申し訳ありませんが、このような何かを書くことです 。

関連する問題