def _serialize_value(self, attr_name, ignore_serializers=None):
        obj_serializer = self._get_related_serializer(attr_name)
        # To prevent infinite recursion, allow serializers to be ignored
        if ignore_serializers and obj_serializer in ignore_serializers:
            return None

        val = get_property(self.instance, attr_name)

        # If we have one or more related models
        if obj_serializer and hasattr(val, 'all'):
            return [obj_serializer(instance=o).serialize(ignore_serializers=[self.__class__]) for o in val.all()]
        elif obj_serializer:
            return obj_serializer(instance=val).serialize(ignore_serializers=[self.__class__])
        elif hasattr(self.opts.model, attr_name):
            # Check if the field is a relation of any kind
            field_type = getattr(self.opts.model, attr_name)
            # Reverse FK
            if isinstance(field_type, ReverseSingleRelatedObjectDescriptor):
                rel = get_property(self.instance, attr_name)
                if rel:
                    val = rel.pk
            # FK
            elif isinstance(field_type, ForeignRelatedObjectsDescriptor):
                val = list(get_property(self.instance, attr_name).all().values_list('pk', flat=True))
            elif isinstance(field_type, ReverseManyRelatedObjectsDescriptor):
                val = list(get_property(self.instance, attr_name).all().values_list('pk', flat=True))
            elif isinstance(field_type, ManyRelatedObjectsDescriptor):
                val = list(get_property(self.instance, attr_name).all().values_list('pk', flat=True))

        # Serialize the field
        return serialize_field(val)
Example #2
0
 def get_changed_fields(self):
     changed_fields = []
     for k, v in self._pre_save_state.items():
         val = get_property(self, k)
         if val != v:
             changed_fields.append(k)
     return changed_fields
    def _serialize_value(self, attr_name, ignore_serializers=None):
        obj_serializer = self._get_related_serializer(attr_name)
        # To prevent infinite recursion, allow serializers to be ignored
        if ignore_serializers and obj_serializer in ignore_serializers:
            return None

        val = get_property(self.instance, attr_name)

        # If we have one or more related models
        if obj_serializer and hasattr(val, 'all'):
            return [
                obj_serializer(instance=o).serialize(
                    ignore_serializers=[self.__class__]) for o in val.all()
            ]
        elif obj_serializer:
            return obj_serializer(instance=val).serialize(
                ignore_serializers=[self.__class__])
        elif hasattr(self.opts.model, attr_name):
            # Check if the field is a relation of any kind
            field_type = getattr(self.opts.model, attr_name)
            # Reverse FK
            if isinstance(field_type, ReverseSingleRelatedObjectDescriptor):
                rel = get_property(self.instance, attr_name)
                if rel:
                    val = rel.pk
            # FK
            elif isinstance(field_type, ForeignRelatedObjectsDescriptor):
                val = list(
                    get_property(self.instance,
                                 attr_name).all().values_list('pk', flat=True))
            elif isinstance(field_type, ReverseManyRelatedObjectsDescriptor):
                val = list(
                    get_property(self.instance,
                                 attr_name).all().values_list('pk', flat=True))
            elif isinstance(field_type, ManyRelatedObjectsDescriptor):
                val = list(
                    get_property(self.instance,
                                 attr_name).all().values_list('pk', flat=True))

        # Serialize the field
        return serialize_field(val)
Example #4
0
 def _set_pre_save_state(self):
     """
     Set the state of the model before any changes are done,
     so it's possible to determine what fields have changed.
     """
     relevant_fields = self._get_relevant_fields()
     for field in relevant_fields:
         val = get_property(self, field)
         if hasattr(self._serializer, field):
             continue
         if val is None:
             self._pre_save_state[field] = None
             continue
         self._pre_save_state[field] = val
Example #5
0
 def test_get_property(self):
     text_model = TextModel.objects.create(text='test')
     val = model_tools.get_property(text_model, 'text')
     self.assertEqual(val, text_model.text)
Example #6
0
 def test_get_invalid_related_property(self):
     parent = ParentModel.objects.create(name='a parent')
     ChildModel.objects.create(number=12, parent=parent)
     self.assertIsNone(
         model_tools.get_property(parent, 'parent__invalid_property__p'))
Example #7
0
 def test_get_related_property(self):
     parent = ParentModel.objects.create(name='a parent')
     child = ChildModel.objects.create(number=12, parent=parent)
     val = model_tools.get_property(child, 'parent__name')
     self.assertEqual(val, parent.name)
Example #8
0
 def test_get_invalid_property(self):
     text_model = TextModel.objects.create(text='test')
     val = model_tools.get_property(text_model, 'invalidprop')
     self.assertIsNone(val)