对Djangoffi使用CSVWidget的Textarea

2024-09-30 14:33:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用django-filter为大型数据集提供搜索表单。它是为那些想提供样本ID并得到过滤列表的科学家准备的。在

为此,我希望使用<textarea>而不是{},因为他们只需一次粘贴十几个或更多的id,如果他们有提交值的概述,那就更好了。在

这是我的代码:

from django import forms
import django_filters as filters

class TextareaCSVWidget(filters.widgets.BaseCSVWidget, forms.Textarea):
    """
    The widget should create textarea.
    """
    pass

class CharInFilter(filters.BaseInFilter, filters.CharFilter):
    """
    The filter should accept coma separated strings.
    """
    pass

class SampleFilter(filters.FilterSet):
    sample_ids = CharInFilter(
        name='sample_id',
        widget=TextareaCSVWidget()
    )

现在文本区域正确显示。搜索工作如预期。在

但是有一个奇怪的问题:当我输入多个值(用coma分隔)时,在提交搜索表单后,textarea被<input type="text">替换(输入的值被保留)。这看起来很尴尬,我需要阻止这种行为。在

如果在textarea中输入一个值,则不会发生这种情况。在

我的方法有什么问题?在

编辑:

在发布了这个问题之后,我仔细查看了django-filter的源代码,下面是我用来创建TextareaCSVWidget的类BaseCSVWidget的相关部分:

^{pr2}$

强调的部分是决定性的。我现在该怎么办?重写render方法在我看来并不可取。我不想丢失输入的值。在

如果没有其他帮助的话,我可以用JavaScript操作它,并在文档加载时用textarea替换input元素。在


Tags: thedjangoimportid表单formspasswidget
1条回答
网友
1楼 · 发布于 2024-09-30 14:33:33

我重写了render方法,它工作得很好。我的解决方案是:

def render(self, name, value, attrs=None):
    if not self._isiterable(value):
        value = [value]

    if len(value) <= 1:
        # delegate to main widget (Select, etc...) if not multiple values
        value = value[0] if value else ''
        return super(TextareaCSVWidget, self).render(name, value, attrs)

     value = ','.join(value)
     return super(TextareaCSVWidget, self).render(name, value, attrs)

重点是变化。这将正确呈现textarea,并保留用户输入。我想作者在创建这个小部件时没有考虑到HTML元素textarea,因此强制使用一个input元素作为typetext。例如在<input type="number">中放置多个coma分隔值是不可能的。在

如果有人有更好的解决方案,我还是很乐意得到更好的答案。在

相关问题 更多 >