【问题标题】:How to override Django Admin AutoComplete widget wrapper如何覆盖 Django Admin AutoComplete 小部件包装器
【发布时间】:2020-11-01 17:19:19
【问题描述】:

我正在尝试覆盖管理员中的 AutoComplete 小部件。该字段通常包含在另一个小部件中:RelatedFieldWrapper,我需要在上传文件后将动态变量传递给它。

更多上下文:我所做的是从文件中获取一些值,并将它们用作初始数据来创建一堆内联表单集(可以在保存之前查看和编辑)。这很好,但其中一列是Autocomplete。我无法将数据传递给该字段,因为它需要一个我不会提前知道的外键,所以我将数据作为自动完成字段包装器中的额外文本(也称为提示)发送到该字段,以便用户知道在实际自动完成中实际搜索的项目。

到目前为止,这是我所拥有的:

class ChartItemForm(forms.ModelForm):
    hint = forms.CharField(widget=forms.HiddenInput)
    title = forms.ModelChoiceField(queryset=Title.objects.none()) # autocomplete field

    def __init__(self, *args, **kwargs):
        super(ChartItemForm, self).__init__(*args, **kwargs)
        
        # if there's a hint, we pass it to a custom wrapper around the autocomplete
        if 'hint' in self.initial:
            hint = self.initial['hint']
            self.fields['title'].widget = AutoCompleteWrapperWithHint(
             AutocompleteSelect(self.instance._meta.get_field('title').remote_field, site._registry.get(Title).admin_site,), 
             self.instance._meta.get_field('title').remote_field, site._registry.get(Chart).admin_site, hint=hint)

自定义包装器:

class AutoCompleteWrapperWithHint(RelatedFieldWidgetWrapper):
    """
    This class is a wrapper to a given widget to add the add icon for the
    admin interface.
    """
    def __init__(self, *args, **kwargs):
        self.hint = kwargs.pop('hint')
        super(AutoCompleteWrapperWithHint, self).__init__(*args, **kwargs)

它很丑,但它有点工作,但我收到了这个错误: 'tuple' object has no attribute 'field'

经过大量挖掘,我发现这是因为自动完成小部件的选择属性没有字段属性。我猜在我的覆盖中,该字段没有被正确初始化为ModelChoiceIterator,我不知道如何解决这个问题。这是每次回溯失败的部分。

...lib/python3.7/site-packages/django/contrib/admin/widgets.py in <setcomp>

            print(dir(self.choices))
            """Return selected options based on the ModelChoiceIterator."""
            default = (None, [], 0)
            groups = [default]
            has_selected = False
            selected_choices = {
                str(v) for v in value
                if str(v) not in self.choices.field.empty_values
            }

【问题讨论】:

    标签: python django autocomplete django-admin


    【解决方案1】:

    我最终解决了这个问题,但我会留下我在此处所做的事情,以防有人遇到覆盖这些小部件的相同问题。我的自定义小部件没有获得 queryset 属性,因为我正在使用手动传递的initial 数据,我假设。 所以我需要在初始化之后设置小部件和查询集迭代器 (Title.objects.none()),如下所示:

    class ChartItemForm(forms.ModelForm):
        hint = forms.CharField(widget=forms.HiddenInput)
    
        def __init__(self, *args, **kwargs):
            super(ChartItemForm, self).__init__(*args, **kwargs)
    
            if 'hint' in self.initial:
                hint = self.initial['hint']
                widget = AutoCompleteWrapperWithHint(
                        AutocompleteSelect(self.instance._meta.get_field('title').remote_field, site._registry.get(Title).admin_site,),
                        self.instance._meta.get_field('title').remote_field, site._registry.get(Chart).admin_site, hint=hint
                    )
                self.fields['title'] = forms.ModelChoiceField(queryset=Title.objects.none(), widget=widget)
    
    

    【讨论】:

      猜你喜欢
      • 2012-09-02
      • 2017-05-09
      • 2012-04-10
      • 2011-03-29
      • 2019-07-11
      • 2017-11-24
      • 2017-05-26
      • 2019-05-07
      • 2020-07-31
      相关资源
      最近更新 更多