超过 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"],
)
}
我有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"],
)
}