Пример #1
0
    def process_related_counts_parameters(self, params, value):
        """
        Processes related_counts parameter.

        Can either be a True/False value for fetching counts on all fields, or a comma-separated list for specifying
        individual fields.  Ensures field for which we are requesting counts is a relationship field.
        """
        if utils.is_truthy(params) or utils.is_falsy(params):
            return params

        field_counts_requested = [val for val in params.split(',')]

        countable_fields = {field for field in self.parent.fields if
                            getattr(self.parent.fields[field], 'json_api_link', False) or
                            getattr(getattr(self.parent.fields[field], 'field', None), 'json_api_link', None)}
        for count_field in field_counts_requested:
            # Some fields will hide relationships, e.g. HideIfWithdrawal
            # Ignore related_counts for these fields
            fetched_field = self.parent.fields.get(count_field)

            hidden = fetched_field and isinstance(fetched_field, HideIfWithdrawal) and getattr(value, 'is_retracted', False)

            if not hidden and count_field not in countable_fields:
                raise InvalidQueryStringError(
                    detail="Acceptable values for the related_counts query param are 'true', 'false', or any of the relationship fields; got '{0}'".format(
                        params),
                    parameter='related_counts'
                )
        return field_counts_requested
Пример #2
0
 def convert_value(self, value, field):
     """Used to convert incoming values from query params to the appropriate types for filter comparisons
     :param basestring value: value to be resolved
     :param rest_framework.fields.Field field: Field instance
     """
     if isinstance(field, ser.BooleanField):
         if utils.is_truthy(value):
             return True
         elif utils.is_falsy(value):
             return False
         else:
             raise InvalidFilterValue(value=value, field_type="bool")
     elif isinstance(field, self.DATE_FIELDS):
         try:
             return date_parser.parse(value)
         except ValueError:
             raise InvalidFilterValue(value=value, field_type="date")
     elif isinstance(field, (self.LIST_FIELDS, self.RELATIONSHIP_FIELDS, ser.SerializerMethodField)) or isinstance(
         (getattr(field, "field", None)), self.LIST_FIELDS
     ):
         if value == "null":
             value = None
         return value
     else:
         try:
             return field.to_internal_value(value)
         except ValidationError:
             raise InvalidFilterValue(value=value)
Пример #3
0
    def get_meta_information(self, meta_data, value):
        """
        For retrieving meta values, otherwise returns {}
        """
        meta = {}
        for key in meta_data or {}:
            if key == 'count' or key == 'unread':
                show_related_counts = self.context['request'].query_params.get('related_counts', False)
                if self.context['request'].parser_context.get('kwargs'):
                    if self.context['request'].parser_context['kwargs'].get('is_embedded'):
                        show_related_counts = False
                field_counts_requested = self.process_related_counts_parameters(show_related_counts, value)

                if utils.is_truthy(show_related_counts):
                    meta[key] = website_utils.rapply(meta_data[key], _url_val, obj=value, serializer=self.parent)
                elif utils.is_falsy(show_related_counts):
                    continue
                elif self.field_name in field_counts_requested:
                    meta[key] = website_utils.rapply(meta_data[key], _url_val, obj=value, serializer=self.parent)
                else:
                    continue
            elif key == 'projects_in_common':
                if not get_user_auth(self.context['request']).user:
                    continue
                if not self.context['request'].query_params.get('show_projects_in_common', False):
                    continue
                meta[key] = website_utils.rapply(meta_data[key], _url_val, obj=value, serializer=self.parent)
            else:
                meta[key] = website_utils.rapply(meta_data[key], _url_val, obj=value, serializer=self.parent)
        return meta
Пример #4
0
 def get_meta_information(self, meta_data, value):
     """
     For retrieving meta values, otherwise returns {}
     """
     meta = {}
     for key in meta_data or {}:
         if key == 'count':
             show_related_counts = self.context['request'].query_params.get(
                 'related_counts', False)
             if utils.is_truthy(show_related_counts):
                 meta[key] = website_utils.rapply(meta_data[key],
                                                  _url_val,
                                                  obj=value,
                                                  serializer=self.parent)
             elif utils.is_falsy(show_related_counts):
                 continue
             if not utils.is_truthy(show_related_counts):
                 raise InvalidQueryStringError(
                     detail=
                     "Acceptable values for the related_counts query param are 'true' or 'false'; got '{0}'"
                     .format(show_related_counts),
                     parameter='related_counts')
         else:
             meta[key] = website_utils.rapply(meta_data[key],
                                              _url_val,
                                              obj=value,
                                              serializer=self.parent)
     return meta
Пример #5
0
    def to_representation(self, value):
        """
        Returns nested dictionary in format {'links': {'self.link_type': ... }

        If no meta information, self.link_type is equal to a string containing link's URL.  Otherwise,
        the link is represented as a links object with 'href' and 'meta' members.
        """
        url = super(JSONAPIHyperlinkedIdentityField, self).to_representation(value)

        meta = {}
        for key in self.meta or {}:
            if key == 'count':
                show_related_counts = self.context['request'].query_params.get('related_counts', False)
                if utils.is_truthy(show_related_counts):
                    meta[key] = _rapply(self.meta[key], _url_val, obj=value, serializer=self.parent)
                elif utils.is_falsy(show_related_counts):
                    continue
                else:
                    raise InvalidQueryStringError(
                        detail="Acceptable values for the related_counts query param are 'true' or 'false'; got '{0}'".format(show_related_counts),
                        parameter='related_counts'
                    )
            else:
                meta[key] = _rapply(self.meta[key], _url_val, obj=value, serializer=self.parent)

        return {'links': {self.link_type: {'href': url, 'meta': meta}}}
Пример #6
0
    def process_related_counts_parameters(self, params, value):
        """
        Processes related_counts parameter.

        Can either be a True/False value for fetching counts on all fields, or a comma-separated list for specifying
        individual fields.  Ensures field for which we are requesting counts is a relationship field.
        """
        if utils.is_truthy(params) or utils.is_falsy(params):
            return params

        field_counts_requested = [val for val in params.split(',')]

        countable_fields = {field for field in self.parent.fields if
                            getattr(self.parent.fields[field], 'json_api_link', False) or
                            getattr(getattr(self.parent.fields[field], 'field', None), 'json_api_link', None)}
        for count_field in field_counts_requested:
            # Some fields will hide relationships, e.g. HideIfWithdrawal
            # Ignore related_counts for these fields
            fetched_field = self.parent.fields.get(count_field)

            hidden = fetched_field and isinstance(fetched_field, HideIfWithdrawal) and getattr(value, 'is_retracted', False)

            if not hidden and count_field not in countable_fields:
                raise InvalidQueryStringError(
                    detail="Acceptable values for the related_counts query param are 'true', 'false', or any of the relationship fields; got '{0}'".format(
                        params),
                    parameter='related_counts'
                )
        return field_counts_requested
Пример #7
0
    def to_representation(self, value):
        """
        Returns nested dictionary in format {'links': {'self.link_type': ... }

        If no meta information, self.link_type is equal to a string containing link's URL.  Otherwise,
        the link is represented as a links object with 'href' and 'meta' members.
        """
        url = super(JSONAPIHyperlinkedIdentityField,
                    self).to_representation(value)

        meta = {}
        for key in self.meta or {}:
            if key == 'count':
                show_related_counts = self.context['request'].query_params.get(
                    'related_counts', False)
                if utils.is_truthy(show_related_counts):
                    meta[key] = _rapply(self.meta[key],
                                        _url_val,
                                        obj=value,
                                        serializer=self.parent)
                elif utils.is_falsy(show_related_counts):
                    continue
                else:
                    raise InvalidQueryStringError(
                        detail=
                        "Acceptable values for the related_counts query param are 'true' or 'false'; got '{0}'"
                        .format(show_related_counts),
                        parameter='related_counts')
        return {'links': {self.link_type: {'href': url, 'meta': meta}}}
Пример #8
0
 def convert_value(self, value, field):
     """Used to convert incoming values from query params to the appropriate types for filter comparisons
     :param basestring value: value to be resolved
     :param rest_framework.fields.Field field: Field instance
     """
     if isinstance(field, ser.BooleanField):
         if utils.is_truthy(value):
             return True
         elif utils.is_falsy(value):
             return False
         else:
             raise InvalidFilterValue(value=value, field_type='bool')
     elif isinstance(field, self.DATE_FIELDS):
         try:
             return date_parser.parse(value)
         except ValueError:
             raise InvalidFilterValue(value=value, field_type='date')
     elif isinstance(field, (self.LIST_FIELDS, self.RELATIONSHIP_FIELDS, ser.SerializerMethodField)) \
             or isinstance((getattr(field, 'field', None)), self.LIST_FIELDS):
         if value == 'null':
             value = None
         return value
     else:
         try:
             return field.to_internal_value(value)
         except ValidationError:
             raise InvalidFilterValue(value=value, )
Пример #9
0
    def get_meta_information(self, meta_data, value):
        """
        For retrieving meta values, otherwise returns {}
        """
        meta = {}
        for key in meta_data or {}:
            if key == 'count' or key == 'unread':
                show_related_counts = self.context['request'].query_params.get(
                    'related_counts', False)
                field_counts_requested = self.process_related_counts_parameters(
                    show_related_counts, value)

                if utils.is_truthy(show_related_counts):
                    meta[key] = website_utils.rapply(meta_data[key],
                                                     _url_val,
                                                     obj=value,
                                                     serializer=self.parent)
                elif utils.is_falsy(show_related_counts):
                    continue
                elif self.field_name in field_counts_requested:
                    meta[key] = website_utils.rapply(meta_data[key],
                                                     _url_val,
                                                     obj=value,
                                                     serializer=self.parent)
                else:
                    continue
            else:
                meta[key] = website_utils.rapply(meta_data[key],
                                                 _url_val,
                                                 obj=value,
                                                 serializer=self.parent)
        return meta
Пример #10
0
 def convert_value(self, value, field):
     """Used to convert incoming values from query params to the appropriate types for filter comparisons
     :param basestring value: value to be resolved
     :param rest_framework.fields.Field field: Field instance
     """
     if isinstance(field, ser.BooleanField):
         if utils.is_truthy(value):
             return True
         elif utils.is_falsy(value):
             return False
         else:
             raise InvalidFilterValue(
                 value=value,
                 field_type='bool'
             )
     elif isinstance(field, self.DATE_FIELDS):
         try:
             return date_parser.parse(value)
         except ValueError:
             raise InvalidFilterValue(
                 value=value,
                 field_type='date'
             )
     elif isinstance(field, self.LIST_FIELDS):
         return value
     else:
         try:
             return field.to_internal_value(value)
         except ValidationError:
             raise InvalidFilterValue(
                 value=value,
             )
Пример #11
0
 def convert_value(self, value, field):
     field_type = type(self.serializer_class._declared_fields[field])
     value = value.strip()
     if field_type == ser.BooleanField:
         if utils.is_truthy(value):
             return True
         elif utils.is_falsy(value):
             return False
         # TODO Should we handle if the value is neither TRUTHY nor FALSY (first add test for how we'd expect it to
         # work, then ensure that it works that way).
     else:
         return value
Пример #12
0
 def convert_value(self, value, field):
     field_type = type(self.serializer_class._declared_fields[field])
     value = value.strip()
     if field_type == ser.BooleanField:
         if utils.is_truthy(value):
             return True
         elif utils.is_falsy(value):
             return False
         # TODO Should we handle if the value is neither TRUTHY nor FALSY (first add test for how we'd expect it to
         # work, then ensure that it works that way).
     else:
         return value
Пример #13
0
 def convert_special_params_to_odm_query(self, field_name, query_params, key, data):
     if isinstance(data, list):
         if utils.is_falsy(query_params[key]):
             # Use `or` when looking for not-preprints, to include both no file and is_orphaned
             sub_query = functools.reduce(operator.or_, [
                 MQ(item['source_field_name'], item['op'], item['value'])
                 for item in data
             ])
         else:
             sub_query = functools.reduce(operator.and_, [
                 MQ(item['source_field_name'], item['op'], item['value'])
                 for item in data
             ])
         return sub_query
     else:
         raise InvalidFilterError('Expected type list for field {}, got {}'.format(field_name, type(data)))
Пример #14
0
 def convert_special_params_to_odm_query(self, field_name, query_params, key, data):
     if isinstance(data, list):
         if utils.is_falsy(query_params[key]):
             # Use `or` when looking for not-preprints, to include both no file and is_orphaned
             sub_query = functools.reduce(operator.or_, [
                 Q(item['source_field_name'], item['op'], item['value'])
                 for item in data
             ])
         else:
             sub_query = functools.reduce(operator.and_, [
                 Q(item['source_field_name'], item['op'], item['value'])
                 for item in data
             ])
         return sub_query
     else:
         raise InvalidFilterError('Expected type list for field {}, got {}'.format(field_name, type(data)))
Пример #15
0
 def convert_value(self, value, field):
     """Used to convert incoming values from query params to the appropriate types for filter comparisons
     :param basestring value: value to be resolved
     :param rest_framework.fields.Field field: Field instance
     """
     field = utils.decompose_field(field)
     if isinstance(field, ShowIfVersion):
         field = field.field
     if isinstance(field, ser.BooleanField):
         if utils.is_truthy(value):
             return True
         elif utils.is_falsy(value):
             return False
         else:
             raise InvalidFilterValue(
                 value=value,
                 field_type='bool',
             )
     elif isinstance(field, self.DATE_FIELDS):
         try:
             ret = date_parser.parse(value, ignoretz=False)
             if not ret.tzinfo:
                 ret = ret.replace(tzinfo=pytz.utc)
             return ret
         except ValueError:
             raise InvalidFilterValue(
                 value=value,
                 field_type='date',
             )
     elif isinstance(field,
                     (self.RELATIONSHIP_FIELDS, ser.SerializerMethodField,
                      ser.ManyRelatedField)):
         if value == 'null':
             value = None
         return value
     elif isinstance(field, self.LIST_FIELDS) or isinstance(
         (getattr(field, 'field', None)), self.LIST_FIELDS):
         if value == 'null':
             value = []
         return value
     else:
         try:
             return field.to_internal_value(value)
         except ValidationError:
             raise InvalidFilterValue(value=value, )
Пример #16
0
 def convert_value(self, value, field):
     """Used to convert incoming values from query params to the appropriate types for filter comparisons
     :param basestring value: value to be resolved
     :param rest_framework.fields.Field field: Field instance
     """
     field = utils.decompose_field(field)
     if isinstance(field, ShowIfVersion):
         field = field.field
     if isinstance(field, ser.BooleanField):
         if utils.is_truthy(value):
             return True
         elif utils.is_falsy(value):
             return False
         else:
             raise InvalidFilterValue(
                 value=value,
                 field_type='bool',
             )
     elif isinstance(field, self.DATE_FIELDS):
         try:
             ret = date_parser.parse(value, ignoretz=False)
             if not ret.tzinfo:
                 ret = ret.replace(tzinfo=pytz.utc)
             return ret
         except ValueError:
             raise InvalidFilterValue(
                 value=value,
                 field_type='date',
             )
     elif isinstance(field, (self.RELATIONSHIP_FIELDS, ser.SerializerMethodField)):
         if value == 'null':
             value = None
         return value
     elif isinstance(field, self.LIST_FIELDS) or isinstance((getattr(field, 'field', None)), self.LIST_FIELDS):
         if value == 'null':
             value = []
         return value
     else:
         try:
             return field.to_internal_value(value)
         except ValidationError:
             raise InvalidFilterValue(
                 value=value,
             )
Пример #17
0
 def get_meta_information(self, meta_data, value):
     """
     For retrieving meta values, otherwise returns {}
     """
     meta = {}
     for key in meta_data or {}:
         if key == 'count' or key == 'unread':
             show_related_counts = self.context['request'].query_params.get('related_counts', False)
             if utils.is_truthy(show_related_counts):
                 meta[key] = website_utils.rapply(meta_data[key], _url_val, obj=value, serializer=self.parent)
             elif utils.is_falsy(show_related_counts):
                 continue
             if not utils.is_truthy(show_related_counts):
                 raise InvalidQueryStringError(
                     detail="Acceptable values for the related_counts query param are 'true' or 'false'; got '{0}'".format(show_related_counts),
                     parameter='related_counts'
                 )
         else:
             meta[key] = website_utils.rapply(meta_data[key], _url_val, obj=value, serializer=self.parent)
     return meta
Пример #18
0
    def get_meta_information(self, meta_data, value):
        """
        For retrieving meta values, otherwise returns {}
        """
        meta = {}
        for key in meta_data or {}:
            if key == 'count' or key == 'unread':
                show_related_counts = self.context['request'].query_params.get('related_counts', False)
                field_counts_requested = self.process_related_counts_parameters(show_related_counts, value)

                if utils.is_truthy(show_related_counts):
                    meta[key] = website_utils.rapply(meta_data[key], _url_val, obj=value, serializer=self.parent)
                elif utils.is_falsy(show_related_counts):
                    continue
                elif self.field_name in field_counts_requested:
                    meta[key] = website_utils.rapply(meta_data[key], _url_val, obj=value, serializer=self.parent)
                else:
                    continue
            else:
                meta[key] = website_utils.rapply(meta_data[key], _url_val, obj=value, serializer=self.parent)
        return meta