【问题标题】:Django form post not savingDjango表单帖子未保存
【发布时间】:2020-12-09 14:28:12
【问题描述】:

我正在制作一个 Django 应用程序(这是我人生中的第一次)。作为应用程序的一部分,需要实施时间表。将数据(从数据库)加载到时间表中可以正常工作: Timetable view

问题是数据应该是可编辑的。因此用户需要能够更改时间或是/否参数。我在views.py 中创建了一个POST 处理程序,但是当我按下保存时,页面会快速重新加载并且旧值又回来了。我做错了什么?

models.py

class timeTable(models.Model):
    key = models.CharField(max_length=200, unique=True, null=True)
    value = models.CharField(max_length=200, null=True)

    def __str__(self):
        return self.key

views.py

@login_required(login_url='login')
def timetable(request):
    timeTableFormset = modelformset_factory(timeTable, fields='__all__' ,extra=0)
    timetableform = timeTableFormset(queryset=timeTable.objects.all()) 
    if request.method == 'POST':
        form = timeTableFormset(request.POST)
        if form.is_valid():
            form.save()

    return render(request, 'VulnManager/timetable.html', {'timetableform': timetableform})

时间表.html:

<form method="POST">
                            {% csrf_token %}
                            <table id="tablePreview" class="table table-borderless table-hover">
                            <!--Table head-->
                              <thead>
                                <tr>
                                  <th></th>
                                  <th>Monday</th>
                                  <th>Tuesday</th>
                                  <th>Wednesday</th>
                                  <th>Thursday</th>
                                  <th>Friday</th>
                                  <th>Saturday</th>
                                  <th>Sunday</th>
                                </tr>
                              </thead>
                              <!--Table head-->
                              <!--Table body-->
                              <tbody>
                                <tr>
                                    <th scope="row">Scan?</th>
                                    {{ timetableform.management_form }}
                                    {% for timeTableValue in timetableform.forms %}
                                    {% if forloop.counter <= 7 %}
                                    <td><select class="form-control" id="{{ timeTableValue.key.value }}" disabled="true">
                                        <option>{{ timeTableValue.value.value }}</option>
                                        <option>
                                            {% if timeTableValue.value.value == "true" %}
                                            false
                                            {% elif timeTableValue.value.value == "false" %}
                                            true
                                            {% endif %}
                                        </option>
                                    </select></td>
                                    {% if forloop.counter == 7 %}
                                </tr>
                                <tr>
                                    <th scope="row">Time begin</th>
                                    {% endif %}
                                    {% elif forloop.counter >= 8 and forloop.counter <= 14 %}
                                    <td><input type="text" id="{{ timeTableValue.key.value }}" onchange="validateHhMm(this);" value="{{ timeTableValue.value.value }}" readonly /></td>
                                    {% if forloop.counter == 14 %}
                                </tr>
                                <tr>
                                    <th scope="row">Time end</th>
                                    {% endif %}
                                    {% elif forloop.counter >= 15 and forloop.counter <= 21 %}
                                    <td><input type="text" id="{{ timeTableValue.key.value }}" onchange="validateHhMm(this);" value="{{ timeTableValue.value.value }}" readonly /></td>
                                    {% endif %} 
                                    {% endfor %}
                                </tr>
                              </tbody>
                              <!--Table body-->
                            </table>
                            <input type="button" class="btn-primary" id="edit" value="Edit" />
                            <input type="submit" class="btn-primary" id="save" value="Save" />
                        </form>

【问题讨论】:

    标签: python django django-models django-forms django-templates


    【解决方案1】:

    您的“表单”变量中包含表单集,但您必须单独遍历表单集中的表单:

    if form.is_valid():
        for form_line in form:
            form_line.save()
    

    【讨论】:

    • 我试过了,这并不能解决问题。
    【解决方案2】:

    由于缺少更好的术语,您的视图总是呈现“获取”表单。

    我认为,如果您保持变量名称相同,它会使事情变得更简单和一致。所以解释一下;

    views.py

    @login_required(login_url='login')
    def timetable(request):
        timeTableFormset = modelformset_factory(timeTable, fields='__all__' ,extra=0)
        timetableform = timeTableFormset(queryset=timeTable.objects.all()) 
    
        if request.method == 'POST':
            form = timeTableFormset(request.POST) # This form just gets left in this block
            if form.is_valid():
                form.save()
    
        return render(
            request,
            'VulnManager/timetable.html',
            {'timetableform': timetableform}  # The context includes the fresh new form, with no post data
        )
    

    你应该做的,就是叫它formset,因为它让生活更轻松;

    from django.contrib import messages
    
    
    @login_required(login_url='login')
    def timetable(request):
        timeTableFormset = modelformset_factory(timeTable, fields='__all__' ,extra=0)
    
        formset = timeTableFormset(queryset=timeTable.objects.all()) 
    
        if request.method == 'POST':
            formset = timeTableFormset(data=request.POST, queryset=timeTable.objects.all())
            if formset.is_valid():
                formset.save()
                # Do something here to reassure the user it saved. Redirect or add a message
                messages.success(request, 'Form saved.')
    
        return render(
            request,
            'VulnManager/timetable.html',
            {'timetableform': formset}
        )
    

    这里有一篇文章可能会为您提供一些值得一读的内容; https://medium.com/@MicroPyramid/understanding-djangos-model-fromsets-in-detail-and-their-advanced-usage-131dfe66853d

    【讨论】:

    • 感谢您的回复。当我使用这个。更新后,它在模板中显示“无”作为值。这是什么原因造成的?
    • 很难说。它会更新您的数据吗?如果是这样,我会在保存后添加一个重定向,以将用户发送到他们可能会在保存后去的其他地方。
    • 忘了说;不,它不保存数据。它说“无”。重新加载页面时,旧数据又回来了。按 F5 时,浏览器会提示我有未保存的数据。
    猜你喜欢
    • 2020-07-31
    • 2020-11-09
    • 1970-01-01
    • 2020-12-26
    • 1970-01-01
    • 2020-05-22
    • 1970-01-01
    • 2021-08-13
    相关资源
    最近更新 更多