In the doc example, the GET variable "selected_facets" is used to
indicate "author" is being faceted. But how do I indicate multiple
facets, say author:John & subject:python & publisher:oreily
If I follow the link to say author:John in the doc example, I'd arrive
at the URL:
/search/?q=foo&selected_facets=author:John
What URL do I use to get to the next facet now that selected_facet is
already used by "author"?
FacetedSearchForm() does this to narrow by the selected_facet:
if self.cleaned_data['selected_facets']:
sqs = sqs.narrow(self.cleaned_data['selected_facets'])
But that only deals with 1 facet, right? How do I make it work for
multiple selected facets?
You could introduce a separator character between the selected facets
in the url.
Create a search form like i.e. this:
from django import forms
from haystack.forms import FacetedSearchForm
class MultiFacetSearchForm(FacetedSearchForm):
def search(self):
sqs = super(FacetedSearchForm, self).search()
if self.cleaned_data['selected_facets']:
for f in self.cleaned_data['selected_facets'].split("|"):
sqs = sqs.narrow(f)
return sqs
And use urls like this in your search:
search/?q=john&selected_facets=city_exact:"New York"|
profession_exact:"Doctor"
Then there should be logic disabling select of same facet value twice
etc. But I haven't figured out how to do that in the template yet.
Anders
The documentation thinks you're working with the
``FacetedSearchForm``, which dodges the issue slightly by using a
string with ``.narrow()``. The idea is to concatenate the things you
want to limit by as you wanted. That form/view combination are
definitely on the naive side, but it's difficult to build code that
does everything for everyone, so the idea is demonstrating how to go
about it.
That said, Anders' suggestion would work. You could also chain
multiple ``selected_facets`` (i.e.
``?q=Django&selected_facets=author:John&selected_facets=subject:python&selected_facets=publisher:oreily``).
Django will turn ``selected_facets`` into a list within the
``HttpRequest`` object that you can iterate over and use as you
please.
Daniel
> --
> You received this message because you are subscribed to the Google Groups "django-haystack" group.
> To post to this group, send email to django-...@googlegroups.com.
> To unsubscribe from this group, send email to django-haysta...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/django-haystack?hl=en.
>
>
>
>
When I look at self.cleaned_data['selected_facets'] in debugger, it
returns:
nb_tags:two
Is there a way to get at HttpRequest from
from haystack.forms import FacetedSearchForm
class MyFacetedSearchForm(FacetedSearchForm):
def __name__(self):
return "MyFacetedSearchForm"
selected_facets = forms.CharField(required=False,
widget=forms.HiddenInput)
def search(self):
sqs = super(FacetedSearchForm, self).search()
if self.cleaned_data['selected_facets']:
sqs = sqs.narrow(self.cleaned_data['selected_facets'])
print self.cleaned_data['selected_facets']
assert False
return sqs
Thank you :)
Just cutting my teeth on django.
I need to get my hands on HttpRequest so that I can parse multiple
selected_facets. Looks like it is not available in this context.
If anyone has conquered the ability to narrow search based on multiple
selected_facets, please do share. :)
Thank you :)
In search.html
{% for facet_key, facet_field in facets.fields.items %}
<div class="fieldWrapper">
{{ facet_key }}:
{% for tag, tag_count in facet_field %}
{% ifnotequal tag "None" %}
<a href="{{ request.get_full_path }}
&_fq_{{facet_key}}___{{ tag|urlencode }}">{{ tag }}</
a>({{ tag_count }})
{% endifnotequal %}
{% endfor %}
<br />
</div>
{% endfor %}
---------------
Note in above: &_fq_{{facet_key}}___{{ tag|urlencode }}
will produce a url:
/search/?
q=bill&selected_facets=&_fq_<facet_field>___<facet_tag>&_fq_<facet_field>___<facet_tag>
Then in forms.py
class MyFacetedSearchForm(FacetedSearchForm):
def __name__(self):
return "MyFacetedSearchForm"
selected_facets = forms.CharField(required=False,
widget=forms.HiddenInput)
def search(self):
sqs = super(FacetedSearchForm,
self).search().order_by('fullname_company')
for item in self.data:
if item[0:4] == '_fq_':
facet_tag = item[4:].split('___')
facet = ':'.join(facet_tag)
sqs = sqs.narrow(facet)
return sqs
-------------
The above is a hack and can be cleaned up but it works!!! Now I can
narrow with an arbitrary selection of facets.
Now I need to show currently selected faces to allow user to unselect
facet filters.
As far as getting the results of the ``selected_facets`` into the
form, you'd be best off either serializing all of your facets together
in a single string (like you did, though I've seen people use "|" in
the past instead of many underscores) or ditching the built-in
``FacetedSearchForm`` in favor of a custom, similar form that uses
something like a ``MultipleChoiceField`` (see
http://docs.djangoproject.com/en/1.1/ref/forms/fields/#multiplechoicefield),
which expects a list of items and correctly pulls all of the values
out of the POSTed data.
Otherwise, your overall approach is sane. As far as showing which
facets are selected, you may want to consider post-processing the
facet counts (``FacetedSearchView.extra_context``) with the choices
selected in your form. Once you've got the form down pat, this ought
to mostly fall into place.
Daniel
request.GET.getlist('selected_facets') should do the trick
for: ?
q=Django&selected_facets=author:John&selected_facets=subject:python&selected_facets=publisher:oreily
this will return:
[u'author:John', u'subject:python', u'publisher:oreily']