0

我有一个需要数百个复选框的表单,但是如果用户选择所有这些复选框,则生成的 URL 太长以至于 IE8 将其截断为大约 2000 个字符。

当前实现创建的 URL 如下:

http://example.com?c_$id1=on&c_$id2=on&c$id3=on...etc.

基本上,每个复选框都有一个 ID,并且该 ID 作为参数发送到 URL。

我想将 URL 更改为这样,使用管道分隔的值:

http://example.com?c=$id1|$id2|$id3|$id4...etc.

在客户端,这很容易,因为我已经使用 JavaScript 提交了表单,但在服务器端,我想避免在我的 Django 表单中做太多疯狂的工作,目前这些复选框构造为几百个BooleanFields.

在 Django 表单中反转管道分隔值以使其顺利运行的最佳方法是什么?

其他注意事项:

  1. 我无法将参数更改为更短。
  2. 我不能只发送一个帖子请求,我需要这些 URL 是可收藏的。
  3. 我无法摆脱 IE8 用户……但。
4

1 回答 1

0

我昨天发布后找到了解决方案。这有点蹩脚,但从用户的角度来看,一切似乎都运行良好。

  1. 在 c 的表单中添加一个字段,并将其设置为隐藏小部件:

    c = forms.CharField(required=False, widget=forms.HiddenInput())

  2. 使用循环和数据库查询在其 init 方法中将数百个复选框添加到表单:

    def __init__(self, *args, **kwargs):
        super(SearchForm, self).__init__(*args, **kwargs)
        COURTS = Court.objects.filter(in_use=True).values_list('courtUUID', 'short_name')
        for court in COURTS:
            self.fields['court_' + court[0]] = forms.BooleanField(
                label=court[1],
                required=False,
                initial=True,
                widget=forms.CheckboxInput(attrs={'checked': 'checked'})
            )
    
  3. 通过将c字段的值转换回 clean 方法中的复选框,将两者拉到一起:

    def clean(self):
        # Convert the value in the court field to the various court_* fields
        court_str = cleaned_data.get('c')
        if court_str:
            court_ids = court_str.split(' ')  # Using a pipe here will suck on IE and Chrome (but not FF)
            for id in court_ids:
                cleaned_data['court_%s' % id] = True
    
  4. 在您的模板中向您的用户显示复选框,但使用 JavaScript 填充cGET 参数中的隐藏字段 ( )。

这个解决方案似乎在我们的实时站点上运行,并且即使用户没有启用 javascript 或使用旧 URL(旧复选框仍然有效),它也具有很好的工作优势。

我讨厌的部分是我正在破解 Django 表单,这对他们来说有点不公平。很高兴听到更好的解决方案。

于 2013-10-23T16:00:51.320 回答