I have the model LodgingOffer
with its respective Manager. I want to carry out some searches on it, for which I am using solr
andhaystack
LodgingOfferManager
has the function active() to retrieve the active objects of LodgingOffer
which are active if you have the fieldis_taked = True
class LodgingOfferManager(models.Manager):
def active(self, *args, **kwargs):
return super(LodgingOfferManager, self).filter(is_taked=False).filter(pub_date__lte=timezone.now())
This is the modelLodgingOffer
def get_images_search_path(instance, filename):
return '/'.join(['lodging_offer_images', instance.slug, filename])
class LodgingOffer(models.Model):
created_by = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
ad_title = models.CharField(null=False, blank=False, max_length=255, verbose_name='Título de la oferta')
photo = models.ImageField(upload_to=get_images_search_path,
blank=False, verbose_name='Fotografía',
null=False)
pub_date = models.DateTimeField(auto_now_add=True)
is_taked = models.BooleanField(_('Oferta tomada'),
default=False,)
objects = LodgingOfferManager()
def __str__(self):
return "%s" % self.ad_title
To carry out the searches I have this form:
class LodgingOfferSearchForm(forms.Form):
query = forms.CharField(label='', widget=forms.TextInput())
and the viewLodgingOfferSearch
class LodgingOfferSearch(FormView):
template_name = 'hosts/lodgingoffer_search.html'
form_class = LodgingOfferSearchForm()
def get(self, request, *args, **kwargs):
form = LodgingOfferSearchForm(self.request.GET or None)
return self.render_to_response(self.get_context_data(form=form))
# We get the active object records
# I think that this is not necessary ... ?
def get_queryset(self):
qs = LodgingOffer.objects.active()
return qs
def get_context_data(self, **kwargs):
context = super(LodgingOfferSearch, self).get_context_data(**kwargs)
user = self.request.user
form = LodgingOfferSearchForm(self.request.GET or None)
qs = LodgingOffer.objects.active()
# We pass the results set active offer_list to template via context
context['offer_list'] = qs
# We ask if the form is valid, when perform a search
if form.is_valid():
cd = form.cleaned_data
# We get the results with from haystack.query import SearchQuerySet()
# detailing query from form.
results = SearchQuerySet().models(LodgingOffer)\
.filter(content=cd['query']).load_all()
# Send some context variables to template
total_results = results.count()
context.update({
'cd': cd,
'results':results,
'total_results': total_results,
})
if user.is_authenticated():
context['userprofile'] = user.profile
return context
So, my concern here is that in my template lodgingoffer_search.html
I want to show the existing records from LodgingOffer
when the template is rendered and the records resulting from the search when I perform one as such. According to this intention, I have:
<!-- We render the form input to perform the search -->
<form action="." method="get">
<input type="submit" value="Buscar" class="submit-button">
<div class="formgroup">
<span></span>
{{ form.query }}
</div> <br />
</form>
<!-- We iterate through offer_list active records existing objects -->
{% for offers in offer_list %}
<article class="host full-width" >
<a href="{% url 'host:detail' offers.slug %}">
<div class="img-title-cont">
{% if offers.photo %}
<div class="img" style="background: url('{{ offers.photo.url }}') no-repeat center; background-size:cover;"></div>
{% endif %}
<div class="title-cont">
<h3>{{ offers.ad_title }}</h3>
</div>
</div>
</a>
</article>
{% endfor %}
<!-- We ask if the query is present in the request.GET to perform search -->
{% if "query" in request.GET %}<br />
<p><h3>Ofertas de alojamiento que contengan: "{{ cd.query }}"</h3></p>
<span>Encontrados cerca de {{ total_results }} resultado{{ total_results|pluralize }}</span>
<br /><br />
<!-- We iterate in results set from search performed -->
{% for result in results %}
{% with lodgingoffer=result.object %}
<article class="host full-width" >
<a href="{% url 'host:detail' lodgingoffer.slug %}">
<div class="img-title-cont">
{% if lodgingoffer.photo %}
<div class="img" style="background: url('{{ lodgingoffer.photo.url }}') no-repeat center; background-size:cover;"></div>
{% endif %}
<div class="title-cont">
<h3>{{ lodgingoffer.ad_title }}</h3>
</div>
</div>
</a>
<hr/>
{% endwith %}
{% empty %}
<p>No existen resultados para tu búsqueda de "{{ cd.query }}".</p>
{% endfor %}
</article>
{% endif %}
The inconvenience that I present is that when I enter the form that renders the template lodgingoffer_search.html
I see the existing records of LodgingOffer
and this is fine, it is what I want.
But when I do a search on the form, I get both the existing records for LodgingOffer
, but also the results that match my search.
So, if my result matches some existing record that I show first, then I will have a duplicate record to show, I would show it twice.
In this link it is possible to see the behavior
How can I show the existing records when I enter the template that renders the form, but when I perform a search, only the results that match that search appear?
Why don't you just use a
else
?:In this way, if there is a search, the filtered results are shown, otherwise the results obtained with
active()
.