lundi 23 février 2015

How to filter results using forms in Django (best approach)

I'm kind of new in python/django and I'd like to know: What's the best approach to filter results in Django using forms in a view?


I need to filter candidates by haircolor, according to the model CandidateLook and by status according to CandidateToJob model.


But I'm getting an error: invalid syntax in my forms.py in line: if self.cleaned_data['status']:


If I remove this line, still getting invalid syntax in forms.py in: return job_candidates


Thanks in advance.


Here is my code:



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

class Candidate(models.Model):
user = models.OneToOneField(User, primary_key=True)
photo = models.ImageField(upload_to=user_profile_path)

class CandidateLook(models.Model):
user = models.OneToOneField(User, primary_key=True)
HAIRCOLOR_CHOICES = (
('1', 'Black'),
('2', 'Brown'),
('3', 'Blonde'),
('4', 'Red')
)
haircolor = models.CharField(max_length=2, choices=HAIRCOLOR_CHOICES)

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


Here is my view:



#views.py
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)

# Fetch the sender_id for each unread message.
# Count the number of times that the sender_id was included.
# Then convert the list of tuples into a dictionary for quick lookup.
sent_messages = dict(
self.request.user.received_messages.filter(
read_at__isnull=True
).values('sender_id').annotate(
messages_sent=Count('sender_id')
).values_list('sender_id', 'messages_sent')
)

form_cand = ScreeningForm(self.request.GET)

if form_cand.is_valid():
job_candidates = form_cand.filter_job_candidates(self.object)
else:
job_candidates = self.object.applied_to.all().order_by('candidate')


candidates = []
for candidate in self.object.applied_to.all().order_by('candidate'):
candidate.messages_sent = sent_messages.get(candidate.candidate.user.id)
candidates.append(candidate)
context['candidate_list'] = candidates
context['form_cand'] = form_cand

return context


The forms



#forms.py
class StatusForm(ModelForm):
STATUS_CHOICES = (
('0', 'New'),
('1', 'Not approved'),
('2', 'Approved')
)
status = forms.ChoiceField(required=False, widget=forms.RadioSelect(attrs={'class': ''}), choices=STATUS_CHOICES)

class Meta:
model = CandidateToJob
exclude = ['candidate', 'job']

class HairColorForm(ModelForm):
HAIRCOLOR_CHOICES = (
('1', 'Black'),
('2', 'Brown'),
('3', 'Blonde'),
('4', 'Red')
)
status = forms.ChoiceField(required=False, widget=forms.RadioSelect(attrs={'class': ''}), choices=HAIRCOLOR_CHOICES)

class Meta:
model = CandidateLook

class ScreeningForm(forms.Form):
haircolor = forms.ChoiceField(choices=CandidateLook.HAIRCOLOR_CHOICES, required=False)
status = forms.ChoiceField(choices=CandidateToJob.STATUS_CHOICES, required=False)

def filter_job_candidates(job):
assert self.is_valid()

job_candidates = job.applied_to.all().order_by('candidate')

if self.cleaned_data['haircolor']:
job_candidates = job_candidates.filter(candidate__candidatelook__haircolor=self.cleaned_data['haircolor']

if self.cleaned_data['status']:
job_candidates = job_candidates.filter(status=self.cleaned_data['status']

return job_candidates


And the template:



#html
{{ job.title }}

{% for candidate in candidate_list %}

{{ candidate }}

{% for status in candidate.status %}

{{ candidate.get_status_display }}

{% endfor %}

{% endfor %}

Aucun commentaire:

Enregistrer un commentaire