【问题标题】:Queryset for django-select2 widget being ignoreddjango-select2 小部件的查询集被忽略
【发布时间】:2023-04-10 14:52:02
【问题描述】:

在我的项目中,我大量使用 Django-Select2,尤其是它的 ModelSelect2Widget,因为我的用户经常需要从 2,000-6,000 个项目的列表中进行选择。到目前为止,在我对它的所有使用中,小部件的查询集一直被称为模型的“.all()”实例,供用户选择,并且没有任何问题。

然而,现在,我在项目的不同部分都有实现,为此过滤小部件选项的查询集是必要的。然而,在所有这些情况下,查询集的任何修改似乎都没有效果,我想知道小部件本身是否存在问题。

在主要情况下,数据库中的项目被布尔标记为活动/非活动(大约 65% 非活动),我只需要有活动项目可供最终用户选择。

我能够通过 shell 正确过滤查询。

在表单定义中,任何过滤(“.filter(flag_active=True)”,甚至将查询集设置为“.none()”都没有效果——下拉/自动完成中的选项没有明显变化. 由于它是一个 select2 输入,我一次只能查看少量项目,但最初检索到的人口和我键入时筛选出来的选择都表明没有遵循过滤器。

MODEL:

class Inventory_product_base(models.Model):
    id = models.UUIDField(primary_key=True,default=uuid.uuid4,null=False)
    upc = models.CharField(max_length=96,null=True,blank=True)
    name = models.CharField('Item name',max_length=96,null=False)
    flag_active = models.BooleanField("Active item",default=True)
    price = models.DecimalField(max_digits=8,decimal_places=3,null=True,blank=True)
    unit_of_measure = models.CharField('UOM',max_length=24, choices=UNITS_OF_MEASURE,default='EACH')
    spec = models.CharField(max_length=36,null=True,blank=True)
    category = models.ForeignKey(Inventory_category,on_delete=models.CASCADE,related_name='cat_products')
    subcategory = models.ForeignKey(Inventory_subcategory,on_delete=models.CASCADE,related_name='subcat_products')
    note = models.CharField(max_length=275,null=True,blank=True)

    def __str__(self):
        return str(self.name)

FORM:

class InventoryCatalogUpdateProductsForm(forms.ModelForm):
    parent_product_base = forms.ModelChoiceField(
        queryset=Inventory_product_base.objects.filter(flag_active=True),
        label=u"",
        widget=ModelSelect2Widget(
            model=Inventory_product_base,
            search_fields=['name__icontains'],
            attrs={'data-placeholder': 'Select product...', 'data-width': '100%'},),)

    class Meta():
        model = Inventory_unit_catalog
        fields = ('parent_product_base',)


class InventoryCatalogUpdateAllProductsForm(forms.ModelForm):
    parent_product_base = forms.ModelChoiceField(
        queryset=Inventory_product_base.objects.all(),
        label=u"",
        widget=ModelSelect2Widget(
            model=Inventory_product_base,
            search_fields=['name__icontains'],
            attrs={'data-placeholder': 'Select product...', 'data-width': '100%'},),)

    class Meta():
        model = Inventory_unit_catalog
        fields = ('parent_product_base',)

InventoryCatalogUpdateProductsFormset = modelformset_factory(model=Inventory_unit_catalog,form=InventoryCatalogUpdateProductsForm,extra=10,can_delete=True)

InventoryCatalogUpdateAllProductsFormset = modelformset_factory(model=Inventory_unit_catalog,form=InventoryCatalogUpdateAllProductsForm,extra=10,can_delete=True)

VIEW:
if product_flag == 'active':
    formset = InventoryCatalogUpdateProductsFormset(queryset=parent_unit_catalog.products.filter(flag_active=True))
else:
    formset = InventoryCatalogUpdateAllProductsFormset(queryset=parent_unit_catalog.products.all())

如前所述,如果我将上述查询集更改为 .none() (或其他任何内容,无论是在小部件中还是在视图中),则 select2 字段中呈现的选择没有区别。

我尝试过单独的并行表单和表单集。最初我尝试了一种更复杂的方法,通过添加以下内容来传递参数并在单个表单中选择不同的查询集:

def __init__(self, *args, **kwargs):
    self.product_flag = kwargs.pop('product_flag')
    super(InventoryCatalogAddToForm, self).__init__(*args, **kwargs)
    print("__init__ has product_flag: ",self.product_flag)
    if self.product_flag == 'active':
        self.fields['parent_product_base'].queryset = Inventory_product_base.objects.filter(flag_active=True)
        print("Screened for flag_active=True")
    else:
        self.fields['parent_product_base'].queryset = Inventory_product_base.objects.all()
        print("Screened for flag_active=False")

并且我能够通过调试打印验证正在执行正确的过滤器选择,但没有任何效果。所以我又回到了一种更简单、更直接的单独表单的方法,但仍然没有。

欢迎任何建议。我的项目已经进行了几个月,而 Django-Select2 是其中的基础之一,我不想知道它无法过滤 select2 输入,我需要找到一个替代品。

【问题讨论】:

  • 您是否尝试过通过 shell 创建小部件并检查它的 queryset 属性/get_queryset 方法?如果这些签出被正确过滤,则问题可能出在 select2 AutoResponseView 上。另外:self.fields['parent_product_base'].queryset 设置表单字段的查询集(即允许的验证选项),使用 self.fields[foo].widget.queryset 设置小部件的选项。
  • @CoffeeBasedLifeform 谢谢 - 我没有意识到你可以指定两个不同的查询集(一个用于验证,一个用于小部件),我假设单个集用于两个目的。过滤.widget.queryset 让一切变得不同!请转发您的评论作为答案,我会标记它
  • 耶网点

标签: django django-forms


【解决方案1】:

self.fields['parent_product_base'].queryset 设置表单域的查询集(即允许的验证选择)。

使用self.fields['parent_product_base'].widget.queryset 设置小部件的选择。

【讨论】:

    猜你喜欢
    • 2022-08-09
    • 1970-01-01
    • 2019-05-14
    • 2023-03-14
    • 2020-05-26
    • 2013-04-13
    • 2013-09-04
    • 2014-11-20
    • 2013-03-27
    相关资源
    最近更新 更多