fix: Fix filters on network view

Filters now use OR for multiple choices in the same field
This commit is contained in:
James Graham
2020-04-17 15:04:48 +01:00
parent 19735e9771
commit 75fc169630
2 changed files with 17 additions and 15 deletions

View File

@@ -35,7 +35,7 @@ class PersonForm(forms.ModelForm):
class DynamicAnswerSetBase(forms.Form): class DynamicAnswerSetBase(forms.Form):
field_class = forms.ChoiceField field_class = forms.ModelChoiceField
field_widget = None field_widget = None
field_required = True field_required = True
@@ -43,11 +43,8 @@ class DynamicAnswerSetBase(forms.Form):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
for question in models.RelationshipQuestion.objects.all(): for question in models.RelationshipQuestion.objects.all():
# Get choices from model and add default 'not selected' option
choices = question.choices + [['', '---------']]
field = self.field_class(label=question, field = self.field_class(label=question,
choices=choices, queryset=question.answers,
widget=self.field_widget, widget=self.field_widget,
required=self.field_required) required=self.field_required)
self.fields['question_{}'.format(question.pk)] = field self.fields['question_{}'.format(question.pk)] = field
@@ -85,6 +82,6 @@ class NetworkFilterForm(DynamicAnswerSetBase):
""" """
Form to provide filtering on the network view. Form to provide filtering on the network view.
""" """
field_class = forms.MultipleChoiceField field_class = forms.ModelMultipleChoiceField
field_widget = Select2MultipleWidget field_widget = Select2MultipleWidget
field_required = False field_required = False

View File

@@ -4,6 +4,7 @@ Views for displaying networks of :class:`People` and :class:`Relationship`s.
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.db.models import Q from django.db.models import Q
from django.forms import ValidationError
from django.utils import timezone from django.utils import timezone
from django.views.generic import FormView from django.views.generic import FormView
@@ -38,22 +39,22 @@ class NetworkView(LoginRequiredMixin, FormView):
Add filtered QuerySets of :class:`Person` and :class:`Relationship` to the context. Add filtered QuerySets of :class:`Person` and :class:`Relationship` to the context.
""" """
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
form = context['form'] form: forms.NetworkFilterForm = context['form']
if not form.is_valid():
raise ValidationError
at_time = timezone.now() at_time = timezone.now()
relationship_set = models.Relationship.objects.all() relationship_set = models.Relationship.objects.all()
# Filter answers to relationship questions # Filter answers to relationship questions
for key, value in form.data.items(): for field, values in form.cleaned_data.items():
if key.startswith('question_') and value: if field.startswith('question_') and values:
question_id = key.replace('question_', '', 1)
answer = models.RelationshipQuestionChoice.objects.get(pk=value,
question__pk=question_id)
relationship_set = relationship_set.filter( relationship_set = relationship_set.filter(
# Time filters must be here
Q(answer_sets__replaced_timestamp__gt=at_time) | Q(answer_sets__replaced_timestamp__isnull=True), Q(answer_sets__replaced_timestamp__gt=at_time) | Q(answer_sets__replaced_timestamp__isnull=True),
answer_sets__timestamp__lte=at_time, answer_sets__timestamp__lte=at_time,
answer_sets__question_answers=answer answer_sets__question_answers__in=values
) )
context['person_set'] = serializers.PersonSerializer( context['person_set'] = serializers.PersonSerializer(
@@ -62,11 +63,15 @@ class NetworkView(LoginRequiredMixin, FormView):
).data ).data
context['relationship_set'] = serializers.RelationshipSerializer( context['relationship_set'] = serializers.RelationshipSerializer(
relationship_set, relationship_set.distinct(),
many=True many=True
).data ).data
return context return context
def form_valid(self, form): def form_valid(self, form):
return self.render_to_response(self.get_context_data()) try:
return self.render_to_response(self.get_context_data())
except ValidationError:
return self.form_invalid(form)