超过 3 个模型的 django-autocomplete-light 依赖过滤器

django-autocomplete-light dependant filter over 3 models

我有3个模型。

class FilterDefaultValues(BaseModel):
    value = models.CharField(max_length=255, null=True, blank=True)
    display_value = models.CharField(max_length=255, null=True, blank=True)

class Filter(BaseModel):
    name = models.CharField(max_length=255)
    default_value = models.ManyToManyField(FilterDefaultValues, blank=True)
    
class ProductFilter(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='filters')
    filter = models.ForeignKey(Filter, on_delete=models.CASCADE)
    value = models.ForeignKey(FilterDefaultValues, blank=True, on_delete=models.RESTRICT)

urls.py

class LinkedDataView(autocomplete.Select2QuerySetView):
    def get_queryset(self):
        qs = super(LinkedDataView, self).get_queryset()
        filter = self.forwarded.get('filter', None)

        if filter:
            qs = qs.filter(filter_id=filter)

        return qs


urlpatterns = [
    url(
        '^linked_data/$',
        LinkedDataView.as_view(model=ProductFilter),
        name='linked_data'
    ),
]

forms.py

class ProductFilterForm(forms.ModelForm):
    def clean_test(self):
        filter = self.cleaned_data.get('filter', None)
        value = self.cleaned_data.get('value', None)

        if value and filter and value.filter != filter:
            raise forms.ValidationError('Wrong owner for test')

        return value

    class Meta:
        model = ProductFilter
        fields = ('product', 'filter', 'value', 'value_type', 'product_images', 'is_variation')
        widgets = {
            'value': autocomplete.ModelSelect2(url='linked_data',
                                               forward=('filter',))
        }

    class Media:
        js = (
            'linked_data.js',
        )

我想要的是当用户选择过滤器时在管理面板中,然后值字段必须填充适当的默认值。

但现在我得到的是:当用户选择过滤器时,此处只会填充 productfilter 项目。

我在这里缺少什么?

这是因为您的 LinkedDataView.get_queryset() 方法正在使用模型 ProductFilter,而它应该使用 FilterDefaultValues 模型。

如果您查看 urls.py 文件,LinkedDataView 是用 model=ProductFilter 初始化的。这意味着 LinkedDataView.get_queryset() 方法只会 return ProductFilter 个实例。

相反,您希望能够显示 FilterDefaultValues 个实例的建议,这些实例被 Filter 个实例通过 Filter.default_value 属性引用(多对多)。

为此,您需要创建一个在 FilterDefaultValues:

上运行的新自动完成视图

urls.py

class FilterDefaultValuesAutocompleteView(autocomplete.Select2QuerySetView):
    def get_queryset(self):
        qs = super().get_queryset()
        filter_id = self.forwarded.get("filter", None)
        if filter_id:
            qs = qs.filter(filter__id=filter_id)
        return qs


urlpatterns = [
    url(
        "^filter_default_values_autocomplete/$",
        FilterDefaultValuesAutocompleteView.as_view(model=FilterDefaultValues),
        name="filter_default_values_autocomplete",
    ),
]

然后更新你的表单 class:

forms.py

class ProductFilterForm(forms.ModelForm):
    class Meta:
        model = ProductFilter
        fields = ...
        widgets = {
            "value": autocomplete.ModelSelect2(
                url="filter_default_values_autocomplete",
                forward=["filter"],
            )
        }