# along with Patchwork; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+from django.core.exceptions import ValidationError
from django_filters import FilterSet
from django_filters import IsoDateTimeFilter
-from django_filters import CharFilter
from django_filters import ModelChoiceFilter
+from django.forms import ModelChoiceField
from patchwork.compat import LOOKUP_FIELD
from patchwork.models import Bundle
from patchwork.models import Patch
from patchwork.models import Project
from patchwork.models import Series
+from patchwork.models import State
class TimestampMixin(FilterSet):
fields = ('project', 'series', 'submitter')
+class StateChoiceField(ModelChoiceField):
+
+ def prepare_value(self, value):
+ if hasattr(value, '_meta'):
+ return value.slug
+ else:
+ return super(StateChoiceField, self).prepare_value(value)
+
+ def to_python(self, value):
+ if value in self.empty_values:
+ return None
+ try:
+ value = ' '.join(value.split('-'))
+ value = self.queryset.get(name__iexact=value)
+ except (ValueError, TypeError, self.queryset.model.DoesNotExist):
+ raise ValidationError(self.error_messages['invalid_choice'],
+ code='invalid_choice')
+ return value
+
+
+class StateFilter(ModelChoiceFilter):
+
+ field_class = StateChoiceField
+
+
class PatchFilter(ProjectMixin, FilterSet):
- # TODO(stephenfin): We should probably be using a ChoiceFilter here?
- state = CharFilter(name='state__name')
+ state = StateFilter(queryset=State.objects.all())
class Meta:
model = Patch
- fields = ('project', 'series', 'submitter', 'delegate', 'state',
- 'archived')
+ fields = ('project', 'series', 'submitter', 'delegate',
+ 'state', 'archived')
class CheckFilter(TimestampMixin, FilterSet):
self.assertEqual(patch_obj.id, patch_json['id'])
self.assertEqual(patch_obj.name, patch_json['name'])
self.assertEqual(patch_obj.msgid, patch_json['msgid'])
- self.assertEqual(patch_obj.state.name, patch_json['state'])
+ self.assertEqual(patch_obj.state.slug, patch_json['state'])
self.assertIn(patch_obj.get_mbox_url(), patch_json['mbox'])
# nested fields
self.assertEqual(status.HTTP_200_OK, resp.status_code)
self.assertEqual(0, len(resp.data))
- patch_obj = create_patch()
+ state_obj = create_state(name='Under Review')
+ patch_obj = create_patch(state=state_obj)
# anonymous user
resp = self.client.get(self.api_url())
self.assertNotIn('diff', patch_rsp)
# test filtering by state
- other_state = create_state()
- resp = self.client.get(self.api_url(), {'state': patch_obj.state.name})
+ resp = self.client.get(self.api_url(), {'state': 'under-review'})
self.assertEqual([patch_obj.id], [x['id'] for x in resp.data])
- resp = self.client.get(self.api_url(), {'state': other_state.name})
+ resp = self.client.get(self.api_url(), {'state': 'missing-state'})
self.assertEqual(0, len(resp.data))
# authenticated user