Esempio n. 1
0
    def to_dict(self, refresh_on_empty=True):
        """
        Return dict representation of model.

        Drill down to any relationships and serialize those too.

        Assume that the current object has been loaded (lazy/joined/etc)
        and don't try to expand anything, i.e., just serialize the
        currently loaded data.

        However, with one exception: refresh if current __dict__ is empty.
        """
        d = {}
        descriptors = self.descriptors

        for field, value in six.iteritems(self.__dict__):
            if field not in descriptors:
                # skip non-descriptors
                continue

            if hasattr(value, "to_dict"):
                value = value.to_dict()
            elif is_sequence(value):
                value = [v.to_dict() if hasattr(v, "to_dict") else v for v in value]

            d[field] = value

        if not d and refresh_on_empty and self.session:
            # Model's __dict__ is empty but has a session associated with it.
            # Most likely the model was previously committed which resets the __dict__ state.
            # Refreshing from database will repopulate the model's __dict__.
            self.refresh()
            d = self.to_dict(refresh_on_empty=False)

        return d
Esempio n. 2
0
    def update(self, data_dict=None, strict=False, **kargs):
        '''Update model with arbitrary set of data.'''

        data = data_dict if isinstance(data_dict, dict) else kargs

        updatable_fields = self.strict_update_fields if strict else data.keys()
        relationships = self.relationships

        for field, value in iteritems(data):
            if hasattr(self, field) and field in updatable_fields:
                # consider v a dict if any of its elements are a dict
                if is_sequence(value):
                    is_dict = any([isinstance(val, dict) for val in value])
                else:
                    is_dict = isinstance(value, dict)

                attr = getattr(self, field)

                if hasattr(attr, 'update') and is_dict and not isinstance(attr, dict):
                    # nest calls to attr.update
                    attr.update(value)
                else:
                    if field in relationships and is_dict and not value:
                        # If v is {} and we're trying to update a relationship attribute,
                        # then we need to set to None to nullify relationship value.
                        value = None
                    setattr(self, field, value)
Esempio n. 3
0
    def update(self, data_dict=None, strict=False, **kargs):
        """
        Update model with arbitrary set of data
        """

        data = data_dict if isinstance(data_dict, dict) else kargs

        updatable_fields = self.strict_update_fields if strict else data.keys()
        relationships = self.relationships

        for k, v in six.iteritems(data):
            if hasattr(self, k) and k in updatable_fields:
                # consider v a dict if any of its elements are a dict
                v_is_dict = any([isinstance(_v, dict) for _v in v]) if is_sequence(v) else isinstance(v, dict)

                attr = getattr(self, k)

                if hasattr(attr, "update") and v_is_dict:
                    # nest calls to attr.update if available and input is a data dict
                    attr.update(v)
                else:
                    if k in relationships and v_is_dict and not v:
                        # typically, if v is {}, then we're usually updating a relationship attribute
                        # where the relationship has an empty/null value in the database
                        # (e.g. a frontend sends missing relationship attribute as {})
                        # but if we set a relationship attribute = {}, things blow up
                        # so instead, convert {} to None which is valid for standard relationship attribute
                        v = None
                    setattr(self, k, v)
Esempio n. 4
0
    def to_dict(self):
        '''Return dict representation of model by filtering fields using `self.__to_dict__`.
        '''
        data = {}
        data_fields = self.__to_dict__

        for field in data_fields:
            value = getattr(self, field)

            # Nest calls to `to_dict`. Try to find method on base value, sequence values, or dict values
            if hasattr(value, 'to_dict'):
                value = value.to_dict()
            elif is_sequence(value):
                value = [v.to_dict() if hasattr(v, 'to_dict') else v for v in value]
            elif isinstance(value, dict):
                value = dict([(k, v.to_dict() if hasattr(v, 'to_dict') else v) for k, v in iteritems(value)])

            data[field] = value

        return data