Filter with Choicefield (Django)

Asked

Viewed 525 times

2

Consider my form:

Forms.py

status_list = (
    ('', ''),
    ('c', 'cancelado'),
    ('elab', 'em elaboração'),
    ('p', 'pendente'),
    ('co', 'concluido'),
    ('a', 'aprovado')
)

class StatusSearchForm(forms.Form):
    status = forms.ChoiceField(
        choices=status_list, widget=forms.Select(attrs={'class': 'form-control'}))

template

<form class="navbar-form navbar-right" action="." method="get">
    <!-- status search form -->
    <div class="form-group">
        <label>Status</label>
        {% for radio in status_search_form.status %}
            {{ radio }}
        {% endfor %}
    </div>
    <!-- search form -->
    <div class="form-group">
        <input id="search_box" name="search_box" type="text" placeholder="Localizar..." class="form-control">
        <button type="submit" class="btn btn-success form-control"><span class="glyphicon glyphicon-search"></span></button>
    </div>
</form>

py views.

class ProposalList(ListView):
    template_name = 'core/proposal/proposal_list.html'
    model = Proposal
    paginate_by = 10

    def get_context_data(self, **kwargs):
        context = super(ProposalList, self).get_context_data(**kwargs)
        context.update({'status_search_form': StatusSearchForm(), })
        return context

    def get_queryset(self):
        p = Proposal.objects.all().select_related()
        q = self.request.GET.get('search_box')
        if q is not None:
            try:
                p = p.filter(
                    Q(id__icontains=q) |
                    Q(work__name_work__icontains=q) |
                    Q(work__customer__first_name__icontains=q) |
                    Q(category__category__startswith=q) |
                    Q(employee__user__first_name__startswith=q) |
                    Q(seller__employee__user__first_name__startswith=q) |
                    Q(created__year=q))
            except ValueError:
                pass
        s = self.request.GET.get('status')
        if s is not None:
            p = p.filter(status__exact=s)
        elif s == '':
            p = p
        return p

Question: I wanted when I chose the first 'status' option, that in case it is empty, it returns all the records normally, the problem is that it is returning

http://localhost:8000/proposal/?status=&search_box=

And this returns nothing. But in this case I want to return everything.

What would be the best solution?

1 answer

1

If you want to return everything just check that the value sent is not empty (q != '') and then not perform the filtering.

p = Proposal.objects.all().select_related()
q = self.request.GET.get('search_box')
if not q in [None, '']:
    p = p.filter(
        Q(id__icontains=q) |
        Q(work__name_work__icontains=q) |
        Q(work__customer__first_name__icontains=q) |
        Q(category__category__startswith=q) |
        Q(employee__user__first_name__startswith=q) |
        Q(seller__employee__user__first_name__startswith=q) |
        Q(created__year=q)
    )
  • OK, but still an error: Valueerror at /Proposal/ The __year lookup type requires an integer argument

  • @Regisdasilva why do you think this is happening?

  • Yes because of integer values, but how to treat it?

  • The mistake will happen because created___year requires a value of the type integer to make the consultation and you are passing a kind string that is coming via requesta.GET, you have to see what the user is looking for and with it perform the respective filtering, if you want to filter ano you must pass a number and not a word.

  • Serves Q(created__year=q. strftime('%Y'))) or Q(created__year=int(q))) ?

  • Regis a solution to this question should be answered by creating a new question, the original question has already been answered, can not be extended by the comments, here does not allow space for this.

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.