Django query in DetailView

34 views
Skip to first unread message

Ronaldo Bahia

unread,
Oct 29, 2014, 12:48:16 PM10/29/14
to django...@googlegroups.com
*This question is also in http://stackoverflow.com/questions/26635406/django-query-in-detailview

I have DetailVIew wich returns a list of related objects (m2m throught). It works just fine!

But I need to search for objects'names and it is returning all objects instead of only the related ones.

How can I approach this?

Thanks.

#models.py
class Candidate(models.Model):
    user = models.OneToOneField(User, primary_key=True)
    birth = models.CharField(max_length=50)
    ...

class Job(models.Model):
    candidate = models.ManyToManyField('Candidate', through='CandidateToJob')
    title = models.CharField(max_length=500)
    ...

class CandidateToJob(models.Model):
    job = models.ForeignKey(Job, related_name='applied_to')
    candidate = models.ForeignKey(Candidate, related_name='from_user')
    STATUS_CHOICES = (
       ('1', 'Not approved'),
       ('2', 'Approved'),
       ('3', 'Hired')
    )
    status = models.CharField(max_length=2, choices=STATUS_CHOICES)

My search query

 #views.py
 def get_query(query_string, search_fields):
    query = None # Query to search for every search term
    terms = normalize_query(query_string)
    for term in terms:
        or_query = None # Query to search for a given term in each field
        for field_name in search_fields:
            q = Q(**{"%s__icontains" % field_name: term})
            if or_query is None:
                or_query = q
            else:
                or_query = or_query | q
        if query is None:
            query = or_query
        else:
            query = query & or_query
    return query

def searchcandidate(request, *args, **kwargs):
    query_string = ''
    found_entries = None
    if ('q' in request.GET) and request.GET['q'].strip():
        query_string = request.GET['q']
        entry_query = get_query(query_string, ['candidate__user__first_name',    'candidate__user__last_name'])

        found_entries = CandidateToJob.objects.filter(entry_query).order_by('-candidate')

    return render_to_response('dashboard/candidates_results.html',
            { 'query_string': query_string, 'found_entries': found_entries },
            context_instance=RequestContext(request)
        )

The view with the list of objects(candidates)

class Screening(generic.DetailView):

    model = Job
    template_name = 'dashboard/screening.html'

    def get_context_data(self, **kwargs):
        context = super(Screening, self).get_context_data(**kwargs)
        context['candidate_list'] = self.object.applied_to.all().order_by('candidate')
        return context  

My urls

#urls.py
url(r'^dashboard/job/(?P<pk>\d+)/screening/$', views.Screening.as_view(), name='screening'),
url(r'^dashboard/job/(?P<pk>\d+)/screening/results/$', 'companies.views.searchcandidate', name='searchcandidate'),

And the templates

#html for Screening(DetailView) in which works good
<form class="" method="get" action="{% url 'searchcandidate' job.pk %}">
    <div class="input-group">
        <input name="q" id="id_q" type="text" class="form-control" placeholder="Buscar candidatos por nome" />
        <span class="input-group-btn">
            <button class="btn btn-orange" type="submit">Buscar</button>
        </span>
    </div>
</form>

{% for candidate in candidate_list %}
     {{ candidate }}
{% endfor %}

The one in which is returning all objects instead of only the related ones

#html
{% if found_entries %}
     {% for candidate in found_entries %}
          {{ candidate }}
     {% endfor %}
{% endif %}

Collin Anderson

unread,
Oct 30, 2014, 8:58:07 AM10/30/14
to django...@googlegroups.com
Hello,

I _think_ your code looks right to me, though the query / or_query code is confusing. Print statements could be helpful there to be sure it's actually filtering something.

Does this code work?

def searchcandidate(request):
    query_string
= request.GET.get('q', '').strip()
    found_entries
= []
   
if query_string:
        found_entries
= CandidateToJob.objects.order_by('-candidate')
       
for term in query_string.split():  # or call your normalize_query() here
            q
= Q()
           
for field_name in ['candidate__user__first_name', 'candidate__user__last_name']:

                q
|= Q(**{"%s__icontains" % field_name: term})

            found_entries
.filter(q)
   
return render(request, 'dashboard/candidates_results.html', {'query_string': query_string, 'found_entries': found_entries})

Collin
Reply all
Reply to author
Forward
0 new messages