如何使用Django ModelForm保存许多选项?

时间:2013-12-24 13:35:42

标签: django django-views django-forms

何浩!

以下问题的最佳解决方案是什么?

我有一个剖面模型,其中包含许多问题模型,其中包含一些选择模型:

class Section(models.Model):
    section_text = models.CharField(max_length=255)
    section_description = models.TextField(blank=False)
    slug = models.SlugField(unique=True, null=True)

    def __unicode__(self):
        return self.section_text

    def save(self, *args, **kwargs):
        self.slug = slugify(self.section_text)
        super(Section, self).save(*args, **kwargs)


class Question(models.Model):
    section = models.ForeignKey(Section)
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

    def __unicode__(self):
        return self.question_text


class Choice(models.Model):
    question = models.ForeignKey(Question)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

ModelForm保持简单,因为我只想编辑投票数:

class ChoiceForm(ModelForm):
    class Meta:
        model = Choice
        fields = ['votes']

不确定我是否应该在网址中传递pk,question_id或slug:

url(
    #regex=r'^(?P<question_id>\d+)/$',
    #regex=r'^(?P<slug>[-\w]+)/$',
    regex=r'^vote/$',
    view=vote,
    name='vote'
),

在HTML中,我显示属于某个部分的所有问题+选项(通过question_list):

{% if question_list %}      
    <form action="{% url 'polls:vote' %}" method="post">    
    {% for question in question_list %}
        <fieldset>
            <legend>{{ question.question_text }}</legend>
            {% csrf_token %}
            {% for choice in question.choice_set.all %}
                <input type="radio" name="{{ question.id }}" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
                <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
            {% endfor %}
        </fieldset>
    {% endfor %}
        <input class="button small" type="submit" value="Weiter" />
    </form>
{% endif %}

最后,观点。在这里,我不确定我在做什么圣诞树:

class SectionOverview(ListView):
    model = Section
    context_object_name = 'section_list'
    template_name = 'itbarometer/umfrage.html'

def vote(request):
    if request.method == 'POST':
        form = ChoiceForm(request.POST)
        if form.is_valid():
            f.save()
            return HttpResponseRedirect('polls:thanks')
    else:
        form = ChoiceForm()

    return render(request, 'polls:detail', {'form': form,})

我基本上想要完成的是保存所有用户输入(用户必须检查所有单选按钮 - 可能是后来的多选项和文本字段)到数据库。

现在所做的只是将我重定向到空白页/投票/

我错过了什么?

圣诞快乐!

1 个答案:

答案 0 :(得分:0)

您没有正确使用自己的观点,模板或表单。尽量保持简单。让我们从表格开始。

您的表单

您应该编辑各个字段,以反映您希望它们在模板中显示的方式。例如,如果您希望用户从问题的下拉列表中进行选择,则可以在ModelForm中执行以下操作。请注意,可以从数据库本身提取此信息,但这仅用于说明目的。

QUESTION_CHOICES=(
('text saved in DB', 'Question 1'),
('text saved in DB', 'Question 2'),
)

class MyModel(ModelForm):
questions = forms.ChoiceField(choices=QUESTION_CHOICES)

class Meta:
    model = MyModel

有用的链接 Createing ModelForms Specifying Widgets Working with Forms

您的模板

完成模型表格后,您只需将其实例发送到模板即可。换句话说,您的模板看起来与此类似:

<html>
  <body>
    <form method="post">
    {% csrf_token %}
      {{ form }}
      <input id="save_question" type="submit" value="Save" />
    </form>
  </body>
</html>

您的观点

您似乎正在尝试将基于功能的视图与基于类的视图混合使用。假设您打算使用基于类的视图,则无需创建get_vote函数。相反,重写get()和post()函数。调用类时,它将自动确定它是GET还是POST请求。这是你的一个例子。

def post(self, request, *args, **kwargs):
    self.object = self.get_object()
    form=self.get_form(self.get_form_class())
        if form.is_valid():
            return self.form_valid(form)
    else:
        return self.form_invalid(form)

有用的链接 Classy CBV Using/Creating Views ListView Example