代码之家  ›  专栏  ›  技术社区  ›  vikingosegundo

生成简单调查应用程序的表单

  •  6
  • vikingosegundo  · 技术社区  · 17 年前

    我正在写一个简单调查的应用程序。

    对于可能的答案,我需要“是/现在”、“1/1到5”和一个简短的文本

    在管理员中,它应该是可选的,应该给出什么类型的答案。

    我的模型:

    from django.db import models
    from django.contrib.contenttypes.models import ContentType
    
    CHOICES=((1,'excactly true'),(2,'mostly true'),(3,'mostly untrue'),(4,'untrue'),(5,'I don\'t know '))
    class Answer(models.Model):
        question = models.ForeignKey("Question")
    
    class ChoiceAnswer(Answer):
        answer = models.IntegerField(max_length=1, choices=CHOICES)
        def __unicode__(self):
            return u'%s: %s'%(self.question, self.answer)
    
    class TextAnswer(Answer):
        answer= models.CharField(max_length=255)
        def __unicode__(self):
            return u'%s: %s'%(self.question, self.answer)
    
    class BooleanAnswer(Answer):
        answer= models.BooleanField(choices=((True,'yes'),(False,'no')))
        def __unicode__(self):
            return u'%s: %s'%(self.question, self.answer)
    
    class Question(models.Model):
        question = models.CharField(max_length=255)
        answer_type = models.ForeignKey(ContentType)
    
        def __unicode__(self):
            return u'%s'%self.question
    

    是否有一种(希望是:简单的)生成表单的方法,通过循环遍历所有问题并创建与问题答案类型兼容的答案表单?

    是否可以为 answer_type = models.ForeignKey(ContentType) 所以只显示答案类型?

    1 回复  |  直到 17 年前
        1
  •  11
  •   avenet    8 年前

    当我自己发现一个解决方案时,我会回答我自己的问题:

    模型:

    CHOICES=((1,'exactly true'),(2,'mostly true'),(3,'mostly untrue'),(4,'untrue'),(5,'I don\'t know '))
    
    class Answer(models.Model):
        question = models.ForeignKey("Question")
    
    class ChoiceAnswer(Answer):
        answer = models.IntegerField(max_length=1, choices=CHOICES)
        def __unicode__(self):
            return u'%s: %s'%(self.question, self.answer)
    
    class TextAnswer(Answer):
        answer= models.TextField()
        def __unicode__(self):
            return u'%s: %s'%(self.question, self.answer)
    
    class BooleanAnswer(Answer):
        answer= models.BooleanField(choices=((True,'yes'),(False,'no')))
        def __unicode__(self):
            return u'%s: %s'%(self.question, self.answer)
    
    class Question(models.Model):
        question = models.CharField(max_length=255)
        answer_type = models.ForeignKey(ContentType)
    
        def __unicode__(self):
            return u'%s'%self.question
    

    PYS:

    class ChoiceAnswerForm(forms.ModelForm):
        class Meta:
            model = ChoiceAnswer
            exclude=("question",)
    ChoiceAnswer.form = ChoiceAnswerForm
    
    class BooleanAnswerForm(forms.ModelForm):
        class Meta:
            model = BooleanAnswer
            exclude=("question",)
    BooleanAnswer.form= BooleanAnswerForm
    
    class TextAnswerForm(forms.ModelForm):
        class Meta:
            model = TextAnswer
            exclude=("question",)
    TextAnswer.form = TextAnswerForm
    

    观点:

    #needed for monkey-patching.
    from survey.forms import BooleanAnswerForm, TextAnswerForm, ChoiceAnswerForm 
    
    def index(request):
        questions = Question.objects.all() 
        if request.method == 'POST': # If the form has been submitted...
            print request.POST
            for q in questions :
                try:
                    data ={ u'%s-answer'%q.id: request.POST[u'%s-answer'%q.id]}
                except:
                    data = { u'%s-answer'%q.id: None}
                q.form = q.answer_type.model_class().form(prefix="%s"%q.id, data=data)    
        else:
            for q in questions :
                q.form = q.answer_type.model_class().form(prefix="%s"%q.id) 
    
        return render_to_response('survey.html', {
            'questions': questions,
    
        })  
    

    在模板中:

    {% block content %}
    
        <div class="survey">
            <form enctype="multipart/*" action="/" method="post">
    
            {% for question in questions %}
                <p>{{ question.question }}</p><ul>{{ question.form.as_ul }}</ul>
            {% endfor %}
    
        <div><input type="submit" value="submit" /></div>
    </form>
    </div>
    
    {% endblock %}
    

    猴子修补可以通过某种注册来避免。但现在我对这个没意见。

    编辑

    ContentType过滤可以像

    answer_type = models.ForeignKey(ContentType, 
                  limit_choices_to = Q(name='text answer', app_label='survey')| \
                                     Q(name='boolean answer', app_label='survey')| \
                                     Q(name='choice answer', app_label='survey'))