【问题标题】:How can I use a SplitArrayField in a ModelForm如何在 ModelForm 中使用 SplitArrayField
【发布时间】:2016-12-28 05:13:43
【问题描述】:

我正在尝试将 postgresql ArrayField 显示为用户可以提交数据的表单中的多个输入字段。

假设我有一个模型:

class Venue(models.Model):
    additional_links = ArrayField(models.URLField(validators=[URLValidator]), null=True)

表单正在使用:

class VenueForm(forms.ModelForm):
    class Meta:
        model = Venue
        exclude = ['created_date']
        widgets = {
            'additional_links': forms.Textarea(),
        }

如何让 ArrayField 在 ModelForm 中使用 SplitArrayField?

我试过了:

class VenueForm(forms.ModelForm):
    additional_links = SplitArrayField(forms.TextInput(), size=5, remove_trailing_nulls=True)

    class Meta:
    ..

在 Meta 类小部件中也是如此:

    widgets = {
        'additional_links': forms.SplitArrayField(forms.TextInput(), size=3, remove_trailing_nulls=True)
    }

我也尝试了不同的表单输入/字段,但我总是收到以下错误:

/lib/python3.5/site-packages/django/contrib/postgres/forms/array.py", line 155, in __init__
    widget = SplitArrayWidget(widget=base_field.widget, size=size)
AttributeError: 'TextInput' object has no attribute 'widget'

【问题讨论】:

    标签: python django postgresql python-3.x


    【解决方案1】:

    SplitArrayField 和SplitArrayWidget 是非常不同的东西。 Forms.ModelForm 中的使用 SplitArrayField 正在向表单添加一个新字段。

    SplitArrayWidget 是 SplitArrayField 的默认小部件,因此您无需更改它。

    一个问题是,如果您需要将此小部件设置为“additional_links”字段,因为 ArrayField 的值必须是逗号分隔的值,没有空格。

    示例

    https://www.google.com,https://www.google.com.ru,https://www.google.com.ua

    因此,Django 默认使用 django.forms.widgets.TextInput 作为 ArrayField。这对人类来说非常不舒服。

    但如果您仍想为 ArrayField 使用 SplitArrayWidget,则需要修改此小部件。

    我的版本:

    from django.contrib import postgres
    
    
    class SplitInputsArrayWidget(postgres.forms.SplitArrayWidget):
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
    
        def value_from_datadict(self, data, files, name):
    
            value_from_datadict = super().value_from_datadict(data, files, name)
    
            # convert a list to a string, with commas-separated values
            value_from_datadict = ','.join(value_from_datadict)
    
            return value_from_datadict
    
        def render(self, name, value, attrs=None):
    
            # if object has value, then
            # convert a sting to a list by commas between values
            if value is not None:
                value = value.split(',')
    
            return super().render(name, value, attrs=None)
    

    使用方法:

    型号:

    类文章(models.Model): """ 文章模型 """

    links = ArrayField(
        models.URLField(max_length=1000),
        size=MAX_COUNT_LINKS,
        verbose_name=_('Links'),
        help_text=_('Useful links'),
    )
    

    表格:

    类 ArticleAdminModelForm(forms.ModelForm): """

    """
    
    def __init__(self, *args, **kwargs):
    
        super().__init__(*args, **kwargs)
    
        # field 'links'
        widget_base_field = self.fields['links'].base_field.widget
        count_inputs = self.fields['links'].max_length
        self.fields['links'].widget = SplitInputsArrayWidget(
            widget_base_field,
            count_inputs,
            attrs={'class': 'span12'}
        )
    

    在管理员中的结果:

    Django 1.10(皮肤 Django 套装) Python 3.4

    网络中的有用链接:

    https://docs.djangoproject.com/en/1.10/_modules/django/contrib/postgres/forms/array/#SplitArrayField

    https://bradmontgomery.net/blog/nice-arrayfield-widgets-choices-and-chosenjs/

    更多我的小部件在我的新 Django 项目中(参见文件https://github.com/setivolkylany/programmerHelper/blob/master/utils/django/widgets.py

    不幸的是,现在这段代码没有测试,所以太晚了我会更新我的答案。

    【讨论】:

      猜你喜欢
      • 2017-08-07
      • 2013-05-20
      • 2017-04-14
      • 2012-11-10
      • 2020-07-19
      • 1970-01-01
      • 2012-02-09
      • 2015-12-22
      • 2011-07-07
      相关资源
      最近更新 更多