问题
I would like to have a chained dropdown with elasticsearch as back end using Django. I have two indices in ES and I will use index A for the chained dropdown and index B for the search given contraints selected in index A using common fields.
Like below where after selecting Lv0, Lv1 will be populated depending on the values selected in Lv0. After clicking submit form(I hope this can pass the selected variables to index B for query), query can be made over index B in selected Lv0 and Lv1 only.
I have successfully searched over index B alone many days ago but I have been stuck in adding index A and having it work with index B for a week.
I have below using django-select2.
models.py
class Lv0(models.Model):
name = models.CharField(max_length=255)
class Meta:
ordering = ('name',)
def __str__(self):
return self.name
class Lv1(models.Model):
name = models.CharField(max_length=255)
lv0 = models.ForeignKey('Lv0', related_name="lv1", related_query_name="lv1",on_delete=models.CASCADE)
class Meta:
ordering = ('name',)
def __str__(self):
return self.name
forms.py
from esearch import models
from esearch.models import Lv0, Lv1
#select2 dependent searchable fields
class CateChainedSelect2WidgetForm(forms.Form):
lv0 = forms.ModelChoiceField(
queryset=Lv0.objects.all(),
label='Lv0',
widget=ModelSelect2Widget(
search_fields=['name__icontains'],
max_results=500,
#dependent_fields={'vertical': 'verticals'},
attrs={'data-minimum-input-length': 0},
)
)
lv1 = forms.ModelChoiceField(
queryset=Lv1.objects.all(),
label='Lv1',
widget=ModelSelect2Widget(
search_fields=['name__icontains'],
dependent_fields={'lv0': 'lv0'},
max_results=500,
attrs={'data-minimum-input-length': 0},
)
)
views.py
class TemplateFormView(FormView):
template_name = 'esearch/base.html'
Above only creates two dependent dropdown, and I am lost in how to connect it with ES in class based form.
I have been looking into django-elasticsearch-dsl
but it seems to be mostly for ES indexing? (Please correct me if I am wrong)
I also look into select2 with jquery and ajax. But I can't find an example that populate dropdown with ES which can give me any idea on connection.
Besides autocompleting with index A, I also problem incorporating it to my exisiting search function over index B.
This is what I use to search over index B.
def search_index(request):
results = []
search_term = ""
if request.GET.get('query'):
search_term = request.GET['query']
results = esearch(query=search_term) //this function connects with ES
print(results)
context = {'results': results, 'count': len(results), 'search_term': search_term}
return render(request, 'esearch/index.html', context)
I tried to transform to the Class based View like below, but there is no longer search result.
class TemplateFormView(FormView):
template_name = 'esearch/base.html'
form_class = CateChainedSelect2WidgetForm
def search_index(self, request,*args,**kwargs):
search_term = request.GET.get('query')
results = esearch(query=search_term)
print(results)
context = {'results': results, 'count': len(results), 'search_term': search_term}
return context
base.html
<head>
{{ form.media.css }}
</head>
<body>
<form method="post" action="">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit Form"/>
</form>
<form class="form-inline">
<input
class="form-control mr-sm-2"
type="query" placeholder="query"
aria-label="query"
name = 'query'
value = "">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
来源:https://stackoverflow.com/questions/58075671/django-select2-chained-dropdown-with-elasticsearch