处理 Django 表单

Processing a Django form

我在学习 Django 和改编来自各种在线课程和示例的代码时遇到了使用 Django 表单的问题。因此,代码可能会“混乱”——但如果我能让它按我需要的方式工作,我以后可以改进我的编码风格。

我希望显示包含表单的模板。模板中呈现的页面中显示的部分数据是从一个table/model,polls_CC_Questions中读取的,我希望将页面中输入的数据写到一个相关的table,[=51]中=].

使用的模型是:

class CC_Questions(models.Model):
    q_text = models.CharField('Question text', max_length=200)
    C1_Type = models.CharField('Choice 1 Type', max_length=2)
    Choice1_text = models.CharField('Choice 1 text', max_length=100)
    C2_Type = models.CharField('Choice 2 Type', max_length=2)
    Choice2_text = models.CharField('Choice 2 text', max_length=100)
    #
    def __str__(self):
        return self.q_text[:20]


class CC_Resp_NoFK(models.Model):
    Person_ID = models.IntegerField()
    Test_date = models.DateTimeField('date test taken')
    Q_ID = models.IntegerField()
    Response_value = models.IntegerField(default=0,
        validators=[MaxValueValidator(100), MinValueValidator(-100)])
    #
    def __str__(self):
        return self.Person_ID

现在输入url可以显示包含有效数据的模板: http://localhost:8000/polls/p2vote/4/ 这是在 urls.py

中处理的
app_name = 'polls'
urlpatterns = [
…..
……
    # ex: /polls/p2vote/<q_id>
    path('p2vote/<int:q_id>/', p2_views.p2vote, name='p2vote'),
…..

使用的views.py条目:

def p2vote(request,q_id): 
    #next line has been copied from CC_quest view to GET Question data
    CC_question = get_object_or_404(CC_Questions, pk=q_id)
    #
    if request.method == 'POST':
        form = VoteForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('/polls/p2')
    else:
        formV = VoteForm()
    #context = {'form' : formV}
    return render(request, 'pollapp2/vote.html', {'var_name':CC_question,'form' : VoteForm()})

在forms.py

class VoteForm(forms.ModelForm):
    class Meta:
        model = CC_Resp_NoFK
        fields = ['Person_ID', 'Test_date', 'Q_ID','Response_value']

模板已启动,使用来自 polls_CC_Questions model/table 的数据创建输入字段的标签。这很好用,所以我显示的页面 http://localhost:8000/polls/p2vote/5/ 显示来自CC_Questionstable的数据,“变量varname中携带的”是什么题及其选择。例如模板显示的内容为{{ var_name.q_text }}和{{ var_name.Choice1_text }},见下

此外,显示的包含 ModelForm 的页面可以正确显示标签。使用的模板:

<!-- vote.html based on create.html -->
<!-- 2022-02-17 
Change text on page
Extracted data from CC_Question record passed as varname
-->

{% extends "pollapp2/base.html" %}
<!-- load widget tools to give me more control over layout of form in template -->
{% load widget_tweaks %}
<!-- block Title is the name in the tab -->
{% block title %}Vote on Question{% endblock %}

{% block main %}
<div class="row">
    <div class="col-lg-10 col-lg-offset-2">
        <div class="panel panel-default">
            <div class="panel-heading">
                <h3 class="panel-title">Select one from two choices</h3>
            </div>

            <form method="POST">
            {% csrf_token %}
                <div class="panel-body">
                    <div class="row">
                        <div class="col-lg-12">
                            <div class="form-group">
                                <label for="question">Question to answer</label>
                {{ var_name.q_text }}
                            </div>
                        </div>
                    </div>

                    <div class="row">
                        <div class="col-lg-5">
                            <div class="form-group">
                                <label for="Choice1_text ">Choice 1</label>

            {{ var_name.Choice1_text }}


                            </div>
                        </div>
                        <div class="col-lg-5">
                            <div class="form-group">
                                <label for="option2">Choice 2</label>

            {{ var_name.Choice2_text }}

                            </div>
                        </div>
                       
                    </div>
<!-- Attempt at Input fields follow -->
        <div class="row">
                        <div class="col-lg-12">
                            <div class="form-group">
                                <label for="Person_id">Person ID</label>
    {% render_field form.Person_ID rows="1" class="form-control" %}<br>
                <label for="Test_date">Test Date</label>
    {% render_field form.Test_date rows="1" class="form-control" %}<br>
         <label for="Q_ID">Question ID</label>
    {% render_field form.Q_ID rows="1" class="form-control" %}  <br>
                <label for="Response_value">Response value</label>
    {% render_field form.Response_value rows="1" class="form-control" %}
                            </div>
                        </div>
                </div>
                    <div class="row">
                        <hr />
                        <div class="col-lg-4">
                            <button type="submit" class="btn btn-info">Submit</button>
                        </div>
                    </div>
                </div>
            </form>

        </div>
    </div>
</div>
{% endblock %}  

总结一下。当在浏览器中输入 url : http://localhost:8000/polls/p2vote/X/ 并且“X”是问题的 id 时,在显示页面的意义上,上述所有“有效”,从模型中提取数据:CC_questions。此外,页面上还有由表单 VoteForm 创建的输入框,允许将数据输入 table/model CC_Resp_noFK。 但是,我想要做的不是提供 Q_ID 作为页面中的输入字段,而是用变量 {{ var_name.id }} 中的值填充它。我不知道是否需要以某种方式修改 vote.html 模板,尤其是行:

<label for="Q_ID">Question ID</label>
    {% render_field form.Q_ID rows="1" class="form-control" %}   << change this ??

或视图,在 form.save() 附近的某处 ??

def p2vote(request,q_id): 
    #next line has been copied from CC_quest view to get Question data
    CC_question = get_object_or_404(CC_Questions, pk=q_id)
    #
    if request.method == 'POST':
        form = VoteForm(request.POST)
        if form.is_valid():
            form.save()  << Somewhere around here ??
            return redirect('/polls/p2') 
    else:
        formV = VoteForm()
        #context = {'form' : formV}
        # return render(request, 'pollapp2/vote.html', context)
        # following return tries to send question record into vote.html template
    return render(request, 'pollapp2/vote.html', {'var_name':CC_question,'form' : VoteForm()})

第 1 步:从 VoteForm 中删除 Q_ID。

class VoteForm(forms.ModelForm):
    class Meta:
        model = CC_Resp_NoFK
        fields = ['Person_ID', 'Test_date', 'Response_value']

第 2 步:在检查表单是否有效之后和保存对象之前添加 Q_ID。

def p2vote(request,q_id): 
    #next line has been copied from CC_quest view to get Question data
    CC_question = get_object_or_404(CC_Questions, pk=q_id)
    if request.method == 'POST':
        form = VoteForm(request.POST)
        if form.is_valid():
            item = form.save(commit=False)
            item.Q_ID = q_id
            item.save()
            return redirect('/polls/p2')