【问题标题】:How do I save many options with Django ModelForm?如何使用 Django ModelForm 保存许多选项?
【发布时间】:2013-12-24 13:35:42
【问题描述】:

嗬嗬嗬!

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

我有一个部分模型,其中包含许多问题模型,其中包含几个选择模型:

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']

不确定我是否应该在 url 中传递 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,})

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

它现在所做的只是将我重定向到一个空白页面 /vote/

我错过了什么?

圣诞快乐!

【问题讨论】:

    标签: django django-views django-forms


    【解决方案1】:

    您没有正确使用视图、模板或表单。尽量保持简单。让我们从表单开始。

    您的表单

    您应该编辑各个字段以反映您希望它们在模板中呈现的方式。例如,如果您希望用户从问题的下拉列表中进行选择,您可以在 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

    【讨论】:

    • 感谢您的意见。
    猜你喜欢
    • 1970-01-01
    • 2012-07-23
    • 2022-10-02
    • 2013-05-13
    • 2012-02-27
    • 1970-01-01
    • 2011-06-25
    • 2015-10-08
    • 2020-11-15
    相关资源
    最近更新 更多