[PATCH 1/4] REST: move StateField to a new 'field' module

Philippe Pepiot phil at philpep.org
Mon Jul 17 05:38:22 AEST 2017


On 07/16/2017 09:32 PM, Philippe Pepiot wrote:
> So it can be reused in multiple modules avoiding circular imports.
> 
> Signed-off-by: Philippe Pepiot <phil at philpep.org>
> ---
>  patchwork/api/embedded.py |  1 +
>  patchwork/api/fields.py   | 61 +++++++++++++++++++++++++++++++++++++++++++++++
>  patchwork/api/patch.py    | 42 +-------------------------------
>  3 files changed, 63 insertions(+), 41 deletions(-)
>  create mode 100644 patchwork/api/fields.py
> 
> diff --git a/patchwork/api/embedded.py b/patchwork/api/embedded.py
> index 122422a..ada8ad5 100644
> --- a/patchwork/api/embedded.py
> +++ b/patchwork/api/embedded.py
> @@ -28,6 +28,7 @@ from rest_framework.serializers import HyperlinkedModelSerializer
>  from rest_framework.serializers import SerializerMethodField
>  
>  from patchwork.api.base import CheckHyperlinkedIdentityField
> +from patchwork.api.fields import StateField
>  from patchwork import models
>  
>  

Oops, this hunk should be in patch 2. Feel free to move it while landing
or ask me a V2.

Cheers,

> diff --git a/patchwork/api/fields.py b/patchwork/api/fields.py
> new file mode 100644
> index 0000000..36095bc
> --- /dev/null
> +++ b/patchwork/api/fields.py
> @@ -0,0 +1,61 @@
> +# Patchwork - automated patch tracking system
> +# Copyright (C) 2017 Linaro Corporation
> +#
> +# This file is part of the Patchwork package.
> +#
> +# Patchwork is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 2 of the License, or
> +# (at your option) any later version.
> +#
> +# Patchwork is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with Patchwork; if not, write to the Free Software
> +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> +
> +from django.utils.translation import ugettext_lazy as _
> +from rest_framework.relations import RelatedField
> +
> +from patchwork.models import State
> +
> +
> +def format_state_name(state):
> +    return ' '.join(state.split('-'))
> +
> +
> +class StateField(RelatedField):
> +    """Avoid the need for a state endpoint.
> +
> +    NOTE(stephenfin): This field will only function for State names consisting
> +    of alphanumeric characters, underscores and single spaces. In Patchwork
> +    2.0+, we should consider adding a slug field to the State object and make
> +    use of the SlugRelatedField in DRF.
> +    """
> +    default_error_messages = {
> +        'required': _('This field is required.'),
> +        'invalid_choice': _('Invalid state {name}. Expected one of: '
> +                            '{choices}.'),
> +        'incorrect_type': _('Incorrect type. Expected string value, received '
> +                            '{data_type}.'),
> +    }
> +    queryset = ''  # django 1.6, rest_framework 3.2 require this
> +
> +    def to_internal_value(self, data):
> +        try:
> +            data = format_state_name(data)
> +            return self.get_queryset().get(name__iexact=data)
> +        except State.DoesNotExist:
> +            self.fail('invalid_choice', name=data, choices=', '.join([
> +                format_state_name(x.name) for x in self.get_queryset()]))
> +        except (TypeError, ValueError):
> +            self.fail('incorrect_type', data_type=type(data).__name__)
> +
> +    def to_representation(self, obj):
> +        return obj.slug
> +
> +    def get_queryset(self):
> +        return State.objects.all()
> diff --git a/patchwork/api/patch.py b/patchwork/api/patch.py
> index 1f0ead1..1d0f86c 100644
> --- a/patchwork/api/patch.py
> +++ b/patchwork/api/patch.py
> @@ -19,63 +19,23 @@
>  
>  import email.parser
>  
> -from django.utils.translation import ugettext_lazy as _
>  from rest_framework.generics import ListAPIView
>  from rest_framework.generics import RetrieveUpdateAPIView
> -from rest_framework.relations import RelatedField
>  from rest_framework.reverse import reverse
>  from rest_framework.serializers import HyperlinkedModelSerializer
>  from rest_framework.serializers import SerializerMethodField
>  
>  from patchwork.api.base import PatchworkPermission
> +from patchwork.api.fields import StateField
>  from patchwork.api.filters import PatchFilter
>  from patchwork.api.embedded import PersonSerializer
>  from patchwork.api.embedded import ProjectSerializer
>  from patchwork.api.embedded import SeriesSerializer
>  from patchwork.api.embedded import UserSerializer
>  from patchwork.models import Patch
> -from patchwork.models import State
>  from patchwork.parser import clean_subject
>  
>  
> -def format_state_name(state):
> -    return ' '.join(state.split('-'))
> -
> -
> -class StateField(RelatedField):
> -    """Avoid the need for a state endpoint.
> -
> -    NOTE(stephenfin): This field will only function for State names consisting
> -    of alphanumeric characters, underscores and single spaces. In Patchwork
> -    2.0+, we should consider adding a slug field to the State object and make
> -    use of the SlugRelatedField in DRF.
> -    """
> -    default_error_messages = {
> -        'required': _('This field is required.'),
> -        'invalid_choice': _('Invalid state {name}. Expected one of: '
> -                            '{choices}.'),
> -        'incorrect_type': _('Incorrect type. Expected string value, received '
> -                            '{data_type}.'),
> -    }
> -    queryset = ''  # django 1.6, rest_framework 3.2 require this
> -
> -    def to_internal_value(self, data):
> -        try:
> -            data = format_state_name(data)
> -            return self.get_queryset().get(name__iexact=data)
> -        except State.DoesNotExist:
> -            self.fail('invalid_choice', name=data, choices=', '.join([
> -                format_state_name(x.name) for x in self.get_queryset()]))
> -        except (TypeError, ValueError):
> -            self.fail('incorrect_type', data_type=type(data).__name__)
> -
> -    def to_representation(self, obj):
> -        return obj.slug
> -
> -    def get_queryset(self):
> -        return State.objects.all()
> -
> -
>  class PatchListSerializer(HyperlinkedModelSerializer):
>  
>      project = ProjectSerializer(read_only=True)
> 



More information about the Patchwork mailing list