表格的每一行中的 Django 表单

Posted

技术标签:

【中文标题】表格的每一行中的 Django 表单【英文标题】:Django form in every row of a table 【发布时间】:2016-07-03 18:21:57 【问题描述】:

我想在表格的每一行都有一个简单的文本表单。

预期结果的小提琴图:https://jsfiddle.net/wstg759f/1/

我的Models.py

class Person(models.Model):
    name = models.CharField(max_length=30)

class Quality(models.Model):
    name = models.CharField(max_length=30)
    person=models.ForeignKey(Person)

我有一个查询集,它返回所有人的汇总列表、每个人的素质计数、此人的一项随机素质:

[
'the_count': 5, u'randomquality': u'Nice’, u'person__name': u'Joe', 
'the_count': 4, u'randomquality': u'Generous’,u'person__name': u'Mike', 
'the_count': 4, u'randomquality': u'Healthy’,u'person__name': u'John’', 
..
]

我的 view.html(质量是我的查询集)

<table>
    <thead>
        <tr>
            <th>Person</th>
            <th>Qualities count</th>
            <th>One random quality</th>
            <th>Add a Quality?</th>
        </tr>
    </thead>
    <tbody>
    %for obj in qualities%
    <tr>
            <td> obj.person__name </td>
            <td> obj.the_count  </td>
            <td> obj.randomquality  </td>
            <td>text form to submit a quality for this person</td>
    </tr>
    % endfor %
    </tbody>
</table>

用户应该可以在文本字段中输入一个质量,一旦提交就会被添加到模型中,文本字段被替换为“谢谢,提交” 提交表单必须是独立的。 我没有明确的方向在哪里看。 你会怎么做?

从我的阅读中,我知道 formset 可能是一个解决方案,但它们对我来说真的不清楚。 在这种情况下我什至应该使用 django 形式吗? 如果是,我相信表单应该从模板中获取参数:我不需要用户告诉我人名,因为它已经在这里了。 让我知道我是否可以澄清。 提前致谢。

作为奖励,也许以后,我想避免页面刷新。 ajax 是唯一的方法吗?

【问题讨论】:

formsets 非常适合这种情况,如果您真的想同时提交所有行并重新加载整个页面。您的另一种选择是通过 AJAX 调用来实现这一点,然后您可以简单地仅提交具有文本的行(通过单个按钮),或者通过每个或上的按钮一次提交每一行(或通过文本中的 onChange 事件) ,具体取决于您要完成的工作)。 查看了您的 jsfiddle 示例...绝对是 jQuery 和 AJAX 调用的工作。 更多的是考虑单独提交它们(每行一次通过一个按钮)。如果我使用 Jquery 和 ajax,我还需要 formset 吗?我还想保留 modelform 的优势以进行验证。无论如何,我应该从哪里开始? FormSet 确实是您想要的,这很简单 - 只需调用 MyFormSet = formset_factory(MyForm),然后在模板中遍历它。通读文档中的相关部分,他们有一些很好的例子,很容易理解 检查。我只是有一个疑问:formset生成的表格可以独立吗? (即每行通过一个按钮一次一个) 【参考方案1】:

您可以使用 ajax、表单和视图来做到这一点

模板.html

<table>
    <thead>
        <tr>
            <th>Person</th>
            <th>Qualities count</th>
            <th>One random quality</th>
            <th>Add a Quality?</th>
            <th>Button</th>
        </tr>
    </thead>
    <tbody>
    % for obj in qualities %
    <tr id="row_ obj.id ">
            <td> obj.person__name </td>
            <td> obj.the_count  </td>
            <td> obj.randomquality  </td>
            <td> form.quality </td>
            <td><button value=" obj.id " onclick="addQuality(this.value)">Add</button></td>
    </tr>
    % endfor %
    </tbody>
</table>
<script>
    function addQuality(id_object) 
        const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value
        let data_to_backend = new FormData()
        let qualityToAdd = document.getElementById(`id_$id_object-quality`).value
        if (qualityToAdd !== '') 
            data_to_backend.append('quality', qualityToAdd)
            data_to_backend.append('object_index', id_object)
         else return
        const request = new Request("./", 
        
            method: 'POST',
            headers: 'X-CSRFToken': csrftoken,
            body: data_to_backend
        )
        fetch(request, 
            method: 'POST',
            mode: 'same-origin'
        ).then(
            function(response) 
                if (response.status === 200) 
                    let tableRow = document.getElementById(`row_$ id_object `)
                    tableRow.innerHTML = "<p>thanks, submitted</p>"
                 else 
                    alert("Error")
                    console.log(response)
                
            
        )
    
</script>

设置您的视图以接收发布请求或创建一个新的 url 路径和另一个视图

views.py

def addQuantity(request, codigo_orcamento):
    if request.method == "POST":
        form = formAddQuantity(request.POST)
        if form.is_valid():
            id_object = form.cleaned_data['object_index']
            quality = form.cleaned_data['quality']
            # get the object and add this quality
            return HttpResponse(status=200)
        else:
            return HttpResponse(status=400)
    else:
        return HttpResponse(status=405)

在这个视图中,我们只是检查表单是否有效,从 db 获取对象并在其上添加质量

forms.py

class formAddQuantity(forms.Form):
    object_index = forms.IntegerField(min_value=0)
    quality = forms.CharField(max_length=100)

一个简单的检查,但我建议您为此字段添加更多要求

(未测试,如有错误请告知)

【讨论】:

你能看看this的问题吗?这就是我实际要使用的。

以上是关于表格的每一行中的 Django 表单的主要内容,如果未能解决你的问题,请参考以下文章

表格和表单

Excel VBA GoalSeek 按表格中的每一行

如何为表格中的每一行制作一个接受按钮?

为 OOO Calc 电子表格中的每一行创建新的 txt/html 文件

如何为表格中的每一行创建一个删除按钮?

如何使用 *CSS2* 而不是 CSS3 选择 HTML 表格中的每一行? [复制]