Reputation: 95
I have 3 models.
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',
)
What I want to is in the admin panel when the user selects a filter, then the value field must be populated with appropriate default values.
But now what I get is: When user selects filter then only productfilter items are populated here.
What I am missing here?
Upvotes: 3
Views: 309
Reputation: 15128
This is because your LinkedDataView.get_queryset()
method is using the model ProductFilter
, when it should be using the FilterDefaultValues
model instead.
If you look in your urls.py file, the LinkedDataView
is initialized with model=ProductFilter
. This means that the LinkedDataView.get_queryset()
method will only return ProductFilter
instances.
Instead, you want to be able to show suggestions for FilterDefaultValues
instances that are referenced (many-to-many) by Filter
instances through the Filter.default_value
attribute.
To do this, you'll need to create a new autocomplete view that operates on 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",
),
]
And then update your form class:
forms.py
class ProductFilterForm(forms.ModelForm):
class Meta:
model = ProductFilter
fields = ...
widgets = {
"value": autocomplete.ModelSelect2(
url="filter_default_values_autocomplete",
forward=["filter"],
)
}
Upvotes: 1