【问题标题】:Django - unable to handle form submission with dynamic fieldDjango - 无法使用动态字段处理表单提交
【发布时间】:2021-02-07 23:52:49
【问题描述】:

在我的 Django 表单中,我有一个需要根据当前用户的一些信息动态填充的选择字段。我能够正确设置该字段并在表单中呈现 - 但是,我在提交表单时遇到错误,因为它被我在表单的 __init__ 方法中的一些逻辑挂起,只有首先在生成表单的上下文中是有意义的。我是 Django 的超级新手,对这种情况的设计原则不太熟悉。

在我的应用程序的admin.py 中,我有一个用于为数据导出表单创建自定义视图的方法 - 它的相关部分设置如下......

# admin.py

from organizations.models import Organization
from .forms import ExportForm

class SomeModelAdmin(SimpleHistoryAdmin, SoftDeletionModelAdmin):

    def export_view(self, request):
        authorized_orgs_queryset = Organization.objects.viewable_for_user(request.user).all()
        authorized_orgs = [{'id': org.id, 'name': org.name} for org in authorized_orgs_queryset]

        context = dict(
           self.admin_site.each_context(request),
           form = ExportForm({'authorized_orgs': authorized_orgs}),
        )

        if request.method == 'POST':
            form = ExportForm(request.POST)

            if form.is_valid():
                # do some stuff with the form.cleaned_data and return a .csv file as a response
                return response


       return TemplateResponse(request, 'export.html', context)

因此,当前用户可能被授权为多个组织导出数据,并且我想以表格的形式向用户展示一个填充了这些组织的选择元素。

ExportForm 具有许多始终相同的“固定”字段,并且只有一个动态选择元素,由我传递给它的 authorized_orgs arg 填充 - 它被定义为...

# forms.py

from django import forms

min_year = 1950
export_formats = [
    'csv',
    'xls',
    'xlsx',
    'ods',
    'json',
]

class ExportForm(forms.Form):
    current_year = datetime.datetime.now().year

    export_format = forms.ChoiceField(required=True, label='Format', choices=export_format_choices)
    apply_date_range = forms.BooleanField(required=False)
    year_from = forms.IntegerField(required=False, disabled=True, min_value=min_year, max_value=current_year, initial=current_year)
    year_through = forms.IntegerField(required=False, disabled=True, min_value=min_year, max_value=current_year, initial=current_year)

    def __init__(self, *args, **kwargs):
        super(ExportForm, self).__init__(*args, **kwargs)
        authorized_orgs_choices = [(org['id'], org['name']) for org in args[0]['authorized_orgs']]
        self.fields['authorized_org'] = forms.ChoiceField(required=False, label='Choose an authorized organization', choices=authorized_orgs_choices)

当我渲染表单时,一切都很好。但是,表单提交是出错的地方。提交表单会报错

File "/code/observations/forms.py", line 28, in __init__
  authorized_orgs_choices = [(org['id'], org['name']) for org in args[0]['authorized_orgs']]
File "/usr/local/lib/python3.7/site-packages/django/utils/datastructures.py", line 78, in __getitem__
  raise MultiValueDictKeyError(key)
django.utils.datastructures.MultiValueDictKeyError: 'authorized_orgs'

现在,我明白为什么会发生这种情况 - __init__ 正在从提交的表单中获取值作为其 args,这与我在设置表单时提供的不同。

我不知道在 Django 中通常应该如何处理这种事情......我该如何做到这一点,以便在定义要呈现的表单时正确创建这个动态字段,并且数据是提交后可以在form.cleaned_data 中找到吗?

非常感谢您的任何见解和帮助。

【问题讨论】:

    标签: python django


    【解决方案1】:

    啊哈 - 在这里找到了答案 - django forms post request raising an error on __init__ method

    在处理表单的 POST 时,我需要确保再次传递这些值 - 我还对其进行了一些修改以使用 kwargs -

    # admin.py
    
            if request.method == 'POST':
                form = ExportForm(request.POST, authorized_orgs=authorized_orgs)
    
    # forms.py
    
        def __init__(self, *args, **kwargs):
            super(ExportForm, self).__init__(*args)
            authorized_orgs_choices = [(org['id'], org['name']) for org in kwargs['authorized_orgs']]
            self.fields['authorized_org'] = forms.ChoiceField(required=False, label='Choose an authorized organization', choices=authorized_orgs_choices)
    

    【讨论】:

      猜你喜欢
      • 2014-08-19
      • 2019-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多