如何在Django表单中填充一个隐藏的必填字段?

3
我在Stackoverflow上查看了其他类似的问题,但那些情况不适用于我。
我有一个表单,其中包含一个“队列”字段,这是一个必填字段。这个表单在多个地方使用,在其中一个实例中,我不想向用户显示“队列”字段。因此,我只需在模板上不呈现它即可。但是因为这是一个必填字段,所以表单无法提交。如何在同时隐藏它不让用户看到的同时预先填充此字段?
我不能更改模型或表单的保存方法,因为该表单也在其他地方使用。
forms.py
class PublicTicketForm(CustomFieldMixin, forms.Form):

    queue = forms.ChoiceField(
        widget=forms.Select(attrs={'class': 'form-control'}),
        label=_('Queue'),
        required=True,
        choices=()
    )

views.py:

def no_queue(request):

    if request.method == 'POST':
        form = PublicTicketForm(request.POST, request.FILES)
        form['queue'] = 9 # Tried to assign queue value to field, did not work

        if form.is_valid():
            if text_is_spam(form.cleaned_data['body'], request):
                # This submission is spam. Let's not save it.
                return render(request, template_name='helpdesk/public_spam.html')

            else:
                form.save()
    else:
        form = PublicTicketForm(initial={'queue': 9})  # tried this one too, did not work either
    return render(request, 'helpdesk/no_queue.html', {'form': form})
标签的choices选项是在视图中填充的,但由于我没有在模板中渲染它,所以并没有执行该操作。

为什么要强制要求呢? - Daniel Roseman
因为用户在其他地方应该能够选择将表单信息放入哪个队列,所以我们只在这个地方隐藏它并直接将其发送到ID为9的队列。 - DeA
6个回答

3
您可以使用表单集来为用户分配特定的值并显示特定的输入,就像这个视频中展示的那样。

2

我昨晚刚做了这个!

在forms.py中使用HiddenInput小部件声明字段(确保呈现它):

scope = CharField(max_length=60,widget=HiddenInput())

然后,在views.py中,您可以应用初始值:

form = MyForm(initial={'scope': 'public'})

或者使用CBV:

initial = {'scope':'public'}


我不能在表单中隐藏它,因为该表单也在其他地方使用,所以我能够使用 <input type="hidden" name="queue" value="9" />,这对我起作用了。 - DeA
很高兴它正在工作。我之前没想到的另一件事是子类化表单并在那里进行更改。我们在Django中有许多选项。 - Dashdrum

1

我需要一个页面,使用GET参数填充,但不显示输入字段(以防止用户意外更改对象的配置),因此我在我的admin.py中进行了如下操作:

from django.contrib import admin
from django.forms import HiddenInput

from .models import SimpleNote

class SimpleNoteAdmin(admin.ModelAdmin):
    list_display = ("id",)

    def get_form(self, request, obj=None, change=False, **kwargs):
        form = super(SimpleNoteAdmin, self).get_form(request, obj, change, **kwargs)
        form.base_fields['content_type'].widget = HiddenInput()
        form.base_fields['object_id'].widget = HiddenInput()
        if "content_type" in request.GET and "object_id" in request.GET:  # simple note does not exist, so we must create it using GET parameters
            form.base_fields['object_id'].initial = request.GET['object_id']
            form.base_fields['content_type'].initial = request.GET['content_type']
        return form

admin.site.register(SimpleNote, SimpleNoteAdmin)

1
不要创建隐藏字段。创建另一个表单类,不包含该字段(通过子类化可以避免重复),然后在视图中设置其值。
instance = form.save(commit=False)
instance.queue = 9
instance.save()

1
您可以覆盖POST数据。
if request.method in ('POST', 'PUT'):
    data = request.POST.copy()
    data['queue'] = 9
    form = PublicTicketForm(data, request.FILES)

1
我能在模板中做类似这样的事情,而且它有效!
<input type="hidden" name="queue" value="9" />

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接