1

I doing a form of filtering by the foreignkey field with two search conditions: OR and AND and multiple choices.

forms.py

class EmployeeSkillFilter(forms.ModelForm):
    skills = forms.ModelMultipleChoiceField(queryset=Technology.objects.all(), )

    class Meta:
        model = Employee
        fields = ['skills']

templates.py

<form  method="get" enctype="multipart/form-data">
     {% csrf_token %}
    <input type="checkbox" name="and" value="AND"> Choice and<br>
    <input type="checkbox" name="or" value="OR"> Choice OR<br>

          {{ skill_filter }}
    <button  type="submit" class="btn btn-info" type="button">Go!</button>
</form>

views.py

class AccountList(AuthorizedMixin, ListView):

    model = Employee
    template_name = 'employee_list.html'

    def get_queryset(self, *args, **kwargs):
        condition_and = self.request.GET.get('and', None)
        condition_or = self.request.GET.get('or', None)
        skill = self.request.GET.get('skills', None)
        if condition_and and skill:
            object_list = self.model.objects.filter(skills__name_id=skill) ??????

        if condition_or and tech:
            object_list = self.model.objects.filter(
                Q(skills__name_id=skill) |
                Q(skills__name_id=skill)
            ) ?????
        else:
            object_list = self.model.objects.all()

My urls looks like

localhost://....or=OR&skills=5&skills=4&skills=3

The problem is that when I select multiple objects in a form, I don't know how to pass them all to the condition

skills__name_id=skill 
1
  • 1
    What is request.GET.get('skills')? What do you get from there? Commented Jul 26, 2019 at 10:14

1 Answer 1

1

Use the __in lookup [Django-doc] lookup, and in case of and logic, count the number of matches:

from django.db.models import Count

class AccountList(AuthorizedMixin, ListView):

    model = Employee
    template_name = 'employee_list.html'

    def get_queryset(self, *args, **kwargs):
        condition_and = self.request.GET.get('and', None)
        condition_or = self.request.GET.get('and', None)
        skills = self.request.GET.getlist('skills')
        if condition_and:
            object_list = self.model.objects.filter(
                skills__in=skills
            ).annotate(
                nskills=Count('skills')
            ).filter(
                nskills=len(skills)
            )
        elif condition_or:
            object_list = self.model.objects.filter(
                skills__in=skills
            ).distinct()
        else:
            object_list = self.model.objects.all()
Sign up to request clarification or add additional context in comments.

5 Comments

thanks for your reply. I trying you code and OR condition working good, but AND doesn't produce any results.
I also made a mistake in the question by specifying an incorrect get('and', None) value in views.py code for the OR condition. I fixed the question but it also does not work with this AND.
@Jekson: I made a type (skill instead of skill). The and evidently means the employee must have all technologies as skills. Are you sure that is the case?
my inattention, in your code everything is correct, the problem was in my template.html. Excellent answer!
@Jekson: by using a JOIN on the skills if there are multiple skills that match, it would mean that the employee is returned once per matched skill. So if you have an employee that has skills 2,5,7, and 9, and you select 3, 5, 6, 7, it will be returned two times. The .distinct() prevents that: an employee will only be returned once.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.