Listing existing objects and search results in Django

2

I have the model LodgingOffer with its respective Manager. About I want to do some searches, for which I am using solr and haystack

LodgingOfferManager has the active function () to retrieve the active objects of LodgingOffer which are active if you have the field is_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 model LodgingOffer

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 view LodgingOfferSearch

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 of LodgingOffer when the template is rendered and the records resulting from the search when I make some 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 drawback 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, that's what I want.

But when I do some searching in the form, I get both the existing records of LodgingOffer , but also the results that match my search.

So, if my one result matches some existing record that I show first, then I'll have a duplicate record to show, I'd 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 make a search that only the results that match the search appear?

    
asked by bgarcial 19.01.2018 в 04:47
source

1 answer

2

Why do not you just use a else ?:

<!-- 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 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/>
        </article>
        {% endwith %}
    {% empty %}
        <p>No existen resultados para tu búsqueda de "{{ cd.query }}".</p>
    {% endfor %}
{% else %}
    <!-- 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 %}
{% endif %}

In this way, if there is a search, the filtered results are shown, otherwise the results you get with active() are displayed.

    
answered by 19.01.2018 / 17:55
source