示例#1
0
    def hydrate(self, bundle):
        value = super(DateTimeField, self).hydrate(bundle)

        if value and not hasattr(value, 'year'):
            if isinstance(value, six.string_types):
                try:
                    # Try to rip a date/datetime out of it.
                    value = make_aware(parse(value))
                except (ValueError, TypeError):
                    raise ApiFieldError(
                        "Datetime provided to '%s' field doesn't appear to be a valid datetime string: '%s'"
                        % (self.instance_name, value))

            else:
                raise ApiFieldError(
                    "Datetime provided to '%s' field must be a string: %s" %
                    (self.instance_name, value))

        return value
示例#2
0
    def dehydrate(self, bundle):
        if not bundle.obj or not bundle.obj.pk:
            if not self.null:
                raise ApiFieldError(
                    "The model '%r' does not have a primary key and can not be used in a ToMany context."
                    % bundle.obj)

            return []

        the_m2ms = None

        if isinstance(self.attribute, basestring):
            the_m2ms = getattr(bundle.obj, self.attribute)
        elif callable(self.attribute):
            the_m2ms = self.attribute(bundle)

        if not the_m2ms:
            if not self.null:
                raise ApiFieldError(
                    "The model '%r' has an empty attribute '%s' and doesn't allow a null value."
                    % (bundle.obj, self.attribute))

            return []

        self.m2m_resources = []
        m2m_dehydrated = []

        # TODO: Also model-specific and leaky. Relies on there being a
        #       ``Manager`` there.
        for m2m in the_m2ms.all():
            m2m_resource = self.get_related_resource(m2m)
            m2m_bundle = Bundle(obj=m2m, request=bundle.request)
            # add by zzgvh
            if getattr(bundle, 'related_info', False):
                m2m_bundle.related_info = bundle_related_data_info_factory(
                    parent_bundle=bundle)
                # end add
            self.m2m_resources.append(m2m_resource)
            m2m_dehydrated.append(
                self.dehydrate_related(m2m_bundle, m2m_resource))

        return m2m_dehydrated
示例#3
0
文件: api.py 项目: yenaing/vaas
 def hydrate_cluster(self, bundle):
     try:
         bundle.data['cluster'] = LogicalCluster.objects.get(
             name=bundle.data['cluster'])
     except ObjectDoesNotExist:
         logger.info("[RouteResource.hydrate_cluster()] provided name = %s",
                     bundle.data['cluster'])
         raise ApiFieldError(
             "Could not find the provided cluster via resource name '%s'." %
             bundle.data['cluster'])
     return bundle
示例#4
0
    def set_value_on_bundle_obj(self, bundle, value):
        """
        Overrideable hook for writing a value into the object on a bundle.  Enables the use of
        custom setters in your app code if setattr() is too raw for your fancy ORM model.
        """

        try:
            setattr(bundle.obj, self.attribute, value)
        except Exception, e:
            raise ApiFieldError("The '%s' field couldn't set value '%s': %s" %
                                (self.instance_name, value, e))
示例#5
0
 def dehydrate_related(self, bundle, related_resource, for_list=True):
     if self.check is not None:
         if not self.check(bundle):
             if not self.null:
                 raise ApiFieldError("The field '%s' does not pass \
                         permission check and does not support null" %
                                     (self.attribute))
             else:
                 return None
     return super(CheckToManyField, self).dehydrate_related(
         bundle, related_resource, for_list)
示例#6
0
    def resource_from_uri(self, fk_resource, uri, request=None, related_obj=None, related_name=None):
        """
        Given a URI is provided, the related resource is attempted to be
        loaded based on the identifiers in the URI.
        """
        err_msg = "Could not find the provided %s object via resource URI '%s'." % (fk_resource._meta.resource_name, uri,)

        if not uri:
            raise ApiFieldError(err_msg)

        try:
            obj = fk_resource.get_via_uri(uri, request=request)
            bundle = fk_resource.build_bundle(
                obj=obj,
                request=request,
                via_uri=True
            )
            return fk_resource.full_dehydrate(bundle)
        except ObjectDoesNotExist:
            raise ApiFieldError(err_msg)
示例#7
0
    def resource_from_data(self, fk_resource, data, request=None, related_obj=None, related_name=None):
        """
        Given a dictionary-like structure is provided, a fresh related
        resource is created using that data.
        """
        # Try to hydrate the data provided.
        data = dict_strip_unicode_keys(data)
        obj = None
        if getattr(fk_resource._meta, 'include_resource_uri', True) and 'resource_uri' in data:
            uri = data['resource_uri']
            err_msg = "Could not find the provided %s object via resource URI '%s'." % (fk_resource._meta.resource_name, uri,)
            try:
                obj = fk_resource.get_via_uri(uri, request=request)
            except ObjectDoesNotExist:
                raise ApiFieldError(err_msg)

        fk_bundle = fk_resource.build_bundle(
            data=data,
            obj=obj,
            request=request
        )

        if related_obj:
            fk_bundle.related_obj = related_obj
            fk_bundle.related_name = related_name

        unique_keys = {
            k: v
            for k, v in data.items()
            if k == 'pk' or (hasattr(fk_resource, k) and getattr(fk_resource, k).unique)
        }

        # If we have no unique keys, we shouldn't go look for some resource that
        # happens to match other kwargs. In the case of a create, it might be the
        # completely wrong resource.
        # We also need to check to see if updates are allowed on the FK resource.
        if not obj and unique_keys:
            try:
                fk_resource.obj_get(fk_bundle, skip_errors=True, **data)
            except (ObjectDoesNotExist, NotFound, TypeError):
                try:
                    # Attempt lookup by primary key
                    fk_resource.obj_get(fk_bundle, skip_errors=True, **unique_keys)
                except (ObjectDoesNotExist, NotFound):
                    pass
            except MultipleObjectsReturned:
                pass

        # If we shouldn't update a resource, or we couldn't find a matching
        # resource we'll just return a populated bundle instead
        # of mistakenly updating something that should be read-only.
        fk_bundle = fk_resource.full_hydrate(fk_bundle)
        fk_resource.is_valid(fk_bundle)
        return fk_bundle
示例#8
0
文件: __init__.py 项目: ekr/ietfdb
    def hydrate(self, bundle):
        value = super(TimedeltaField, self).hydrate(bundle)

        if value and not hasattr(value, 'seconds'):
            if isinstance(value, six.string_types):
                try:
                    match = TIMEDELTA_REGEX.search(value)

                    if match:
                        data = match.groupdict()
                        value = datetime.timedelta(int(data['days']), int(data['hours']), int(data['minutes']), int(data['seconds']))
                    else:
                        raise ValueError()
                except (ValueError, TypeError):
                    raise ApiFieldError("Timedelta provided to '%s' field doesn't appear to be a valid datetime string: '%s'" % (self.instance_name, value))

            else:
                raise ApiFieldError("Datetime provided to '%s' field must be a string: %s" % (self.instance_name, value))

        return value
示例#9
0
    def hydrate(self, bundle):
        location = super(GeoPointField, self).hydrate(bundle)
        if location is None:
            return location

        longitude = location.get('longitude')
        latitude = location.get('latitude')
        if longitude is None or latitude is None:
            raise ApiFieldError(
                'Both longitude and latitude properties are required')

        return Point(longitude, latitude)
示例#10
0
    def hydrate(self, bundle):
        value = super(DecimalField, self).hydrate(bundle)

        if value and not isinstance(value, Decimal):
            try:
                value = Decimal(value)
            except decimal.InvalidOperation:
                raise ApiFieldError(
                    "Invalid decimal string for '%s' field: '%s'" %
                    (self.instance_name, value))

        return value
示例#11
0
    def dehydrate(self, bundle, for_list=True):
        foreign_obj = None
        if callable(self.attribute):
            previous_obj = bundle.obj
            foreign_obj = self.attribute(bundle)
        elif isinstance(self.attribute, six.string_types):
            foreign_obj = bundle.obj

            for attr in self._attrs:
                previous_obj = foreign_obj
                try:
                    foreign_obj = getattr(foreign_obj, attr, None)
                except ObjectDoesNotExist:
                    foreign_obj = None

        if not foreign_obj:
            if not self.null:
                if callable(self.attribute):
                    raise ApiFieldError(
                        "The related resource for resource %s could not be found."
                        % (previous_obj))
                else:
                    raise ApiFieldError(
                        "The model '%r' has an empty attribute '%s' and doesn't allow a null value."
                        % (previous_obj, attr))
            return None

        fk_resource = self.get_related_resource(foreign_obj)
        selected_fields = None
        if self.attribute in bundle.selected_fields.keys():
            if bundle.selected_fields != {}:
                selected_fields = bundle.selected_fields[self.attribute]

        fk_bundle = Bundle(obj=foreign_obj,
                           request=bundle.request,
                           selected_fields=selected_fields)
        return self.dehydrate_related(fk_bundle,
                                      fk_resource,
                                      for_list=for_list)
示例#12
0
    def convert(self, value):
        if value is None:
            return None

        if isinstance(value, six.string_types):
            try:
                year, month, day = value[:10].split('-')

                return datetime_safe.date(int(year), int(month), int(day))
            except ValueError:
                raise ApiFieldError("Date provided to '%s' field doesn't appear to be a valid date string: '%s'" % (self.instance_name, value))

        return value
示例#13
0
 def hydrate_m2m(self, bundle):
     if bundle.data.get(self.instance_name) is None:
         if self.null:
             return []
         else:
             raise ApiFieldError("The '%s' field has no data and doesn't allow a null value." % self.instance_name)
     
     m2m_hydrated = []
     
     for value in bundle.data.get(self.instance_name):
         m2m_hydrated.append(self.build_related_resource(value))
     
     return m2m_hydrated
示例#14
0
文件: __init__.py 项目: ekr/ietfdb
    def convert(self, value):
        if value is None:
            return None

        if isinstance(value, six.string_types):
            match = TIMEDELTA_REGEX.search(value)

            if match:
                data = match.groupdict()
                return datetime.timedelta(int(data['days']), int(data['hours']), int(data['minutes']), int(data['seconds']))
            else:
                raise ApiFieldError("Timedelta provided to '%s' field doesn't appear to be a valid timedelta string: '%s'" % (self.instance_name, value))

        return value
示例#15
0
 def dehydrate(self, bundle, for_list=True):
     if self.check is not None:
         if not self.check(bundle):
             if not self.null:
                 raise ApiFieldError("The field '%s' does not pass \
                         permission check and does not support null" %
                                     (self.attribute))
             else:
                 return None
     result = super(CheckToManyField, self).dehydrate(bundle, for_list)
     # avoid returning [[]]
     if not result or not result[0]:
         return []
     return result
示例#16
0
 def dehydrate(self, bundle):
     try:
         foreign_obj = getattr(bundle.obj, self.attribute)
     except ObjectDoesNotExist:
         foreign_obj = None
     if not foreign_obj:
         if not self.null:
             raise ApiFieldError("The model '%r' has an empty attribute '%s' and doesn't allow a null value." % (bundle.obj, self.attribute))
         
         return None
     
     self.fk_resource = self.get_related_resource(foreign_obj)
     fk_bundle = Bundle(obj=foreign_obj)
     return self.dehydrate_related(fk_bundle, self.fk_resource)
示例#17
0
 def convert(self, value):
     if value is None:
         return None
     
     if isinstance(value, basestring):
         match = DATETIME_REGEX.search(value)
         
         if match:
             data = match.groupdict()
             return datetime_safe.datetime(int(data['year']), int(data['month']), int(data['day']), int(data['hour']), int(data['minute']), int(data['second']))
         else:
             raise ApiFieldError("Datetime provided to '%s' field doesn't appear to be a valid datetime string: '%s'" % (self.instance_name, value))
     
     return value
示例#18
0
 def resource_from_uri(self,
                       fk_resource,
                       uri,
                       request=None,
                       related_obj=None,
                       related_name=None):
     try:
         obj = fk_resource.get_via_uri(uri, request=request)
         fk_resource = self.get_related_resource(obj)
         return super(GenericForeignKeyField,
                      self).resource_from_uri(fk_resource, uri, request,
                                              related_obj, related_name)
     except ObjectDoesNotExist:
         raise ApiFieldError("Could not find the provided object via "
                             "resource URI '%s'." % uri)
示例#19
0
 def resource_from_uri(self, fk_resource, uri, request=None, related_obj=None, related_name=None):
     """
     Given a URI is provided, the related resource is attempted to be
     loaded based on the identifiers in the URI.
     """
     try:
         obj = fk_resource.get_via_uri(uri, request=request)
         subclassed_obj = obj.__class__.objects.filter(id=obj.id).get_subclass()
         related_resource = self.get_related_resource(subclassed_obj)
         bundle = related_resource.build_bundle(
             obj=subclassed_obj,
             request=request
         )
         return related_resource.full_dehydrate(bundle)
     except ObjectDoesNotExist:
         raise ApiFieldError("Could not find the provided object via resource URI '%s'." % uri)
示例#20
0
    def hydrate(self, bundle):
        if self.instance_name not in bundle.data:
            return None

        value = bundle.data[self.instance_name]

        if value is None or len(value) == 0:
            return None

        value = str(value).lstrip('[').rstrip(']')
        try:
            [int(pk) for pk in value.split(',')]
            return value
        except ValueError:
            raise ApiFieldError('The field %s must be an int array or null' %
                                (self.instance_name))
示例#21
0
    def hydrate(self, bundle):
        """
        Takes data stored in the bundle for the field and returns it. Used for
        taking simple data and building a instance object.
        """
        if self.readonly:
            return None

        if not bundle.data.has_key(self.instance_name):
            if getattr(self, 'is_related',
                       False) and not getattr(self, 'is_m2m', False):
                # We've got an FK (or alike field) & a possible parent object.
                # Check for it.
                if bundle.related_obj and bundle.related_name in (
                        self.attribute, self.instance_name):
                    return bundle.related_obj

            if getattr(self, 'is_o2o',
                       False) and not getattr(self, 'is_m2m', False):
                # We've got an FK (or alike field) & a possible parent object.
                # Check for it.
                if bundle.related_obj and bundle.related_name in (
                        self.attribute, self.instance_name):
                    return bundle.related_obj

            if self.blank:
                return None
            elif self.attribute and getattr(bundle.obj, self.attribute, None):
                return getattr(bundle.obj, self.attribute)
            elif self.instance_name and hasattr(bundle.obj,
                                                self.instance_name):
                return getattr(bundle.obj, self.instance_name)
            elif self.has_default():
                if callable(self._default):
                    return self._default()

                return self._default
            elif self.null:
                return None
            else:
                raise ApiFieldError(
                    "The '%s' field has no data and doesn't allow a default or null value."
                    % self.instance_name)

        return bundle.data[self.instance_name]
示例#22
0
    def convert(self, value):
        if value is None:
            return None

        if isinstance(value, str):
            try:
                year, month, day = value[:10].split('-')
                hour, minute, second = value[11:19].split(':')

                return make_aware(
                    datetime_safe.datetime(int(year), int(month), int(day),
                                           int(hour), int(minute),
                                           int(second)))
            except ValueError:
                raise ApiFieldError(
                    "Datetime provided to '%s' field doesn't appear to be a valid datetime string: '%s'"
                    % (self.instance_name, value))

        return value
示例#23
0
    def hydrate(self, bundle):
        """
        Takes data stored in the bundle for the field and returns it. Used for
        taking simple data and building a instance object.
        """
        if self.readonly:
            return None
        if self.instance_name not in bundle.data:
            if self.is_related and not self.is_m2m:
                # We've got an FK (or alike field) & a possible parent object.
                # Check for it.
                if bundle.related_obj and bundle.related_name in (
                        self.attribute, self.instance_name):
                    return bundle.related_obj
            if self.blank:
                return None
            if self.attribute:
                try:
                    val = getattr(bundle.obj, self.attribute, None)

                    if val is not None:
                        return val
                except ObjectDoesNotExist:
                    pass
            if self.instance_name:
                try:
                    if hasattr(bundle.obj, self.instance_name):
                        return getattr(bundle.obj, self.instance_name)
                except ObjectDoesNotExist:
                    pass
            if self.has_default():
                if callable(self._default):
                    return self._default()

                return self._default
            if self.null:
                return None

            raise ApiFieldError(
                "The '%s' field has no data and doesn't allow a default or null value."
                % self.instance_name)

        return bundle.data[self.instance_name]
示例#24
0
    def dehydrate(self, bundle):
        attrs = self.attribute.split('__')
        foreign_obj = bundle.obj

        for attr in attrs:
            previous_obj = foreign_obj
            try:
                foreign_obj = getattr(foreign_obj, attr, None)
            except ObjectDoesNotExist:
                foreign_obj = None

            if not foreign_obj:
                if not self.null:
                    raise ApiFieldError("The model '%r' has an empty attribute '%s' and doesn't allow a null value." % (previous_obj, attr))

                return None

        self.fk_resource = self.get_related_resource(foreign_obj)
        fk_bundle = Bundle(obj=foreign_obj, request=bundle.request)
        return self.dehydrate_related(fk_bundle, self.fk_resource)
示例#25
0
    def build_related_resource(self,
                               value,
                               request=None,
                               related_obj=None,
                               related_name=None):
        """
        Returns a bundle of data built by the related resource, usually via
        ``hydrate`` with the data provided.

        Accepts either a URI, a data dictionary (or dictionary-like structure)
        or an object with a ``pk``.
        """
        self.fk_resource = self.to_class()
        kwargs = {
            'request': request,
            'related_obj': related_obj,
            'related_name': related_name,
        }

        if isinstance(value, basestring):
            # We got a URI. Load the object and assign it.
            return self.resource_from_uri(self.fk_resource, value, **kwargs)
        elif isinstance(value, Bundle):
            # We got a valid bundle object, the RelatedField had full=True
            return value
        elif hasattr(value, 'items'):
            # We've got a data dictionary.
            # Since this leads to creation, this is the only one of these
            # methods that might care about "parent" data.
            return self.resource_from_data(self.fk_resource, value, **kwargs)
        elif hasattr(value, 'pk'):
            # We've got an object with a primary key.
            return self.resource_from_pk(self.fk_resource, value, **kwargs)
        elif isinstance(value, int):
            return self.resource_from_id(self.fk_resource, value, **kwargs)
            # We got a valid pk as int
            return value
        else:
            raise ApiFieldError(
                "The '%s' field was given data that was not a URI, not a dictionary-alike and does not have a 'pk' attribute: %s."
                % (self.instance_name, value))
示例#26
0
    def dehydrate(self, bundle):
        """
        Takes data from the provided object and prepares it for the
        resource.
        """
        if self.attribute is not None:
            # Check for `__` in the field for looking through the relation.
            attrs = self.attribute.split('__')
            current_object = bundle.obj

            for attr in attrs:
                previous_object = current_object
                current_object = getattr(current_object, attr, None)

                if current_object is None:
                    if self.has_default():
                        current_object = self._default
                        # Fall out of the loop, given any further attempts at
                        # accesses will fail miserably.
                        break
                    elif self.null:
                        current_object = None
                        # Fall out of the loop, given any further attempts at
                        # accesses will fail miserably.
                        break
                    else:
                        raise ApiFieldError(
                            "The object '%r' has an empty attribute '%s' and doesn't allow a default or null value."
                            % (previous_object, attr))

            if callable(current_object):
                current_object = current_object()

            return self.convert(current_object)

        if self.has_default():
            return self.convert(self.default)
        else:
            return None
示例#27
0
    def dehydrate(self, bundle):
        try:
            foreign_obj = getattr(bundle.obj, self.attribute)
        except ObjectDoesNotExist:
            foreign_obj = None

        if not foreign_obj:
            if not self.null:
                raise ApiFieldError(
                    "The model '%r' has an empty attribute '%s' and doesn't allow a null value."
                    % (bundle.obj, self.attribute))

            return None

        self.fk_resource = self.get_related_resource(foreign_obj)
        fk_bundle = Bundle(obj=foreign_obj, request=bundle.request)
        # add by zzgvh
        if getattr(bundle, 'related_info', False):
            fk_bundle.related_info = bundle_related_data_info_factory(
                parent_bundle=bundle)
        # end add
        return self.dehydrate_related(fk_bundle, self.fk_resource)
示例#28
0
    def obj_create(self, bundle, **kwargs):
        tags = bundle.data.get("tags")
        user = bundle.request.user
        if not tags:
            raise ApiFieldError("标签错误")

        bundle = super(QuestionResource, self).obj_create(bundle, user=user)

        #文件
        attachments = bundle.data.get("attachment")
        if attachments:
            if not isinstance(attachments, list):
                attachments = [attachments]
            for attachment in attachments:
                qa = QuestionAttachment.objects.get_or_create(question=bundle.obj, attachment_id=int(attachment))[0]

        # 问题标签
        tag_objects = self.set_tag(bundle)
        for t in tag_objects:
            QuestionTag(question=bundle.obj, tag=t).save()

        return bundle
示例#29
0
 def hydrate(self, bundle):
     """
     Takes data stored in the bundle for the field and returns it. Used for
     taking simple data and building a instance object.
     """
     if self.readonly:
         return None
     
     if not bundle.data.has_key(self.instance_name):
         if hasattr(bundle.obj, self.instance_name):
             return getattr(bundle.obj, self.instance_name)
         elif self.has_default():
             if callable(self._default):
                 return self._default()
             
             return self._default
         elif self.null:
             return None
         else:
             raise ApiFieldError("The '%s' field has no data and doesn't allow a default or null value." % self.instance_name)
     
     return bundle.data[self.instance_name]
示例#30
0
    def hydrate_m2m(self, bundle):
        if self.readonly:
            return None

        if bundle.data.get(self.instance_name) is None:
            if self.blank:
                return []
            if self.null:
                return []
            raise ApiFieldError("The '%s' field has no data and doesn't allow a null value." % self.instance_name)

        kwargs = {
            'request': bundle.request,
        }

        if self.related_name:
            kwargs['related_obj'] = bundle.obj
            kwargs['related_name'] = self.related_name

        return [
            self.build_related_resource(value, **kwargs)
            for value in bundle.data.get(self.instance_name)
            if value is not None
        ]