【问题标题】:Django form in every row of a table表格的每一行中的 Django 表单
【发布时间】: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生成的表格可以独立吗? (即每行通过一个按钮一次一个)

标签: ajax django forms django-forms 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的问题吗?这就是我实际要使用的。
猜你喜欢
  • 2021-10-10
  • 2011-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-05
  • 2016-06-17
相关资源
最近更新 更多