Skip to main content
 首页 » 编程设计

python之django 中带有 id 的多个文本字段

2025年05月04日41jirigala

我想在 Django 中处理多个字段。在 PHP 中,我使用生成的 HTML,例如:

<input type="text" name="myfield[1]" /> 
<input type="text" name="myfield[4]" /> 
<input type="text" name="myfield[5]" /> 

其中括号中的数字是来自 db(cookies 或其他来源)的 id。
当我处理这个表单时,我可以通过键(例如 1、4、5)从 $_POST['my field'] 数组中获取值。

我想知道,我怎样才能在 Django 中做同样的事情以及如何处理这样的多个字段? 我之前创建了一个复选框列表。在那里我可以将 id 存储在复选框字段的值中,但它不适用于文本字段,因为在值中我需要用户发送的值。

更新:
我是 Django 和 Python 的新手(几周前才开始使用 Django)。
楷模

from django.contrib.auth.models import User 
 
class Order(models.Model): 
    category = models.ForeignKey(Category) 
    exhibition = models.ForeignKey(Exhibition) 
    user = models.ForeignKey(User) 
    date = models.DateField() 
    ordered = models.IntegerField() 
 
class Exhibition(models.Model): 
    play = models.ForeignKey(Play) 
    date = models.DateTimeField() 
 
class Category(models.Model): 
    name = models.CharField(max_length=30) 
    price = models.IntegerField() 
    total = models.IntegerField() 

查看

from django.forms.models import modelformset_factory 
from tickets.forms import CourierForm 
 
def play_info_courier(request, pk): 
    data = get_object_or_404(Exhibition, pk=pk) 
    CourierFormSet = modelformset_factory(CourierForm, extra=0) 
    orders = Order.objects.filter(exhibition=data).values() 
    formset = CourierFormSet(initial=orders) 
    context = RequestContext(request, {'data': data, 'formset': formset}) 
    return render_to_response('tickets/courier.html', context) 

表格

class CourierForm(forms.ModelForm): 
    class Meta: 
        model = Order 

html

<form method="post" action=""> 
{% csrf_token %} 
{{ formset.management_form }} 
<table class="table table-bordered table-hover"> 
    {% for form in formset.forms %} 
        {% if forloop.first %} 
        <thead> 
            <tr> 
                {% for field in form %} 
                    {% if field.name != 'id' %} 
                        <th>{{ field.label|capfirst }}</th> 
                    {% endif %} 
                {% endfor %} 
            </tr> 
            </thead> 
        {% endif %} 
            <tr> 
                <!-- here is my problem, how can I get username from User 
                or anything else from other related models? --> 
                <td>{{ form.user.username }}</td> 
                <td>{{ form.category.price }}</td> 
                <td>{{ form.date.value }}</td> 
                <td>{{ form.ordered }}</td> 
            </tr> 
   {% endfor %} 
</table> 
<input type="submit" name="order" value="Order"/> 
<input type="submit" name="clean" value="Clean order"/> 
</form> 

请您参考如下方法:

在 Django 中,您使用 formsets实现这样的场景。

示例 View :

from django.shortcuts import render 
from django import forms 
from django.forms.formsets import formset_factory 
 
class TestForm(forms.Form): 
    id = forms.IntegerField(label='id', widget=forms.HiddenInput) 
    value = forms.CharField(label='value') 
 
TestFormSet = formset_factory(TestForm, extra=0) 
 
def test(request): 
    if request.method == 'POST': 
        fs = TestFormSet(request.POST) 
    else: 
        fs = TestFormSet(initial=[ 
            dict(id=1, value='foo'), 
            dict(id=4, value='bar'), 
            dict(id=5, value='baz'), 
        ]) 
    context = { 
        'fs': fs, 
    } 
    return render(request, 'formset/test.html', context) 

formset/test.html 模板:

<!DOCTYPE html> 
<html> 
    <head> 
    </head> 
    <body> 
        <form method="POST">{% csrf_token %} 
            {{ fs.management_form }} 
            {% for form in fs %} 
                {% for field in form %} 
                    <div>{{ field }}</div> 
                {% endfor %} 
                <hr> 
            {% endfor %} 
            <button type="submit">Submit</button> 
        </form> 
        <hr> 
        {{ fs.cleaned_data }} 
    </body> 
</html> 

示例提交数据(fs.cleaned_data):

[ 
    { 
        'id': 1, 
        'value': u'foo' 
    }, 
    { 
        'id': 4, 
        'value': u'bar' 
    }, 
    { 
        'id': 5, 
        'value': u'baz' 
    } 
] 

模型表单集

使用模型表单集,您 cannot generally supply the initial parameter正如您对常规表单集所做的那样 — initial 值将仅适用于 extra 表单,不适用于与模型的实际实例相关联的表单。

当你这样做时:

orders = Order.objects.filter(exhibition=data).values() 
formset = CourierFormSet(initial=orders) 

你可能是这个意思:

orders = Order.objects.filter(exhibition=data) 
formset = CourierFormSet(queryset=orders) 

这将为 Order.objects.filter(exhibition=data) 返回的所有实例实例化一个表单集。之后,表单集中的每个表单都会有一个 instance 属性,保存绑定(bind)到该表单的实际 Order 实例:

<td>{{ form.instance.user.username }}</td> 

请注意,您的代码还有一些其他问题:

  1. 您只呈现表单集中的第一个表单,因为您在 {% if forloop.first %} block 中进行;这不太可能是您真正想要完成的。
  2. 您正在跳过表单的 id 字段;这会将您提交的表单数据与您的初始模型实例分离——您希望将它们作为隐藏字段,这是在您呈现 id 字段时由表单集自动完成的。
  3. modelformset_factory 的第一个参数应该是 model 类,而不是表单类;你可能是说 CourierFormSet = modelformset_factory(Order, form=CourierForm, extra=0)。