
import json
from decimal import Decimal

from django.core.serializers.python import Deserializer as PythonDeserializer
from django.core.serializers.json import Serializer as JSONSerializer
from django.core.serializers.python import _get_model
from django.utils import six

from djmoney.models.fields import MoneyField

Serializer = JSONSerializer


def Deserializer(stream_or_string, **options):
    """
    Deserialize a stream or string of JSON data.
    """
    if not isinstance(stream_or_string, (bytes, six.string_types)):
        stream_or_string = stream_or_string.read()
    if isinstance(stream_or_string, bytes):
        stream_or_string = stream_or_string.decode('utf-8')
    try:
        obj_list = []
        for obj in json.loads(stream_or_string):
            money_fields = {}
            fields = {}
            Model = _get_model(obj["model"])
            for (field_name, field_value) in obj['fields'].iteritems():
                field = Model._meta.get_field(field_name)
                if isinstance(field, MoneyField):
                    money_fields[field_name] = Decimal(
                        field_value.split(" ")[0])
                else:
                    fields[field_name] = field_value
            obj['fields'] = fields

            for obj in PythonDeserializer([obj], **options):
                for field, value in money_fields.items():
                    setattr(obj.object, field, value)
                yield obj
    except GeneratorExit:
        raise


import json
from decimal import Decimal

from django.core.serializers.python import Deserializer as PythonDeserializer
from django.core.serializers.json import Serializer as JSONSerializer
from django.core.serializers.python import _get_model
from django.utils import six

from djmoney.models.fields import MoneyField
from moneyed import Money

Serializer = JSONSerializer


def Deserializer(stream_or_string, **options):
    """
    Deserialize a stream or string of JSON data.
    """
    if not isinstance(stream_or_string, (bytes, six.string_types)):
        stream_or_string = stream_or_string.read()
    if isinstance(stream_or_string, bytes):
        stream_or_string = stream_or_string.decode('utf-8')
    try:
        obj_list = []
        for obj in json.loads(stream_or_string):
            money_fields = {}
            fields = {}
            Model = _get_model(obj["model"])
            for (field_name, field_value) in obj['fields'].iteritems():
                field = Model._meta.get_field(field_name)
                if isinstance(field, MoneyField):
                    money_fields[field_name] = Money(field_value, obj['fields']['%s_currency' % field_name])
                else:
                    fields[field_name] = field_value
            obj['fields'] = fields

            for obj in PythonDeserializer([obj], **options):
                for field, value in money_fields.items():
                    setattr(obj.object, field, value)
                yield obj
    except GeneratorExit:
        raise

Fix for de-serialization. Using vanilla django-money, when one did the following:
Fix for de-serialization.
Using vanilla django-money, when one did the following:

./manage.py dumpdata

the values were saved properly, i.e:

{
  'amount': '12',
  'amount_currency': 'USD',
}

however, after the de-serialization:

./manage.py loaddata [fixtures]

the currencies were omitted.

i have no idea (yet) how to write a test that proves that.. :/

  
  import json
  from decimal import Decimal
  
  from django.core.serializers.python import Deserializer as PythonDeserializer
  from django.core.serializers.json import Serializer as JSONSerializer
  from django.core.serializers.python import _get_model
  from django.utils import six
  
  from djmoney.models.fields import MoneyField
+ from moneyed import Money
  
  Serializer = JSONSerializer
  
  
  def Deserializer(stream_or_string, **options):
      """
      Deserialize a stream or string of JSON data.
      """
      if not isinstance(stream_or_string, (bytes, six.string_types)):
          stream_or_string = stream_or_string.read()
      if isinstance(stream_or_string, bytes):
          stream_or_string = stream_or_string.decode('utf-8')
      try:
          obj_list = []
          for obj in json.loads(stream_or_string):
              money_fields = {}
              fields = {}
              Model = _get_model(obj["model"])
              for (field_name, field_value) in obj['fields'].iteritems():
                  field = Model._meta.get_field(field_name)
                  if isinstance(field, MoneyField):
+                     money_fields[field_name] = Money(field_value, obj['fields']['%s_currency' % field_name])
-                     money_fields[field_name] = Decimal(
-                         field_value.split(" ")[0])
                  else:
                      fields[field_name] = field_value
              obj['fields'] = fields
  
              for obj in PythonDeserializer([obj], **options):
                  for field, value in money_fields.items():
                      setattr(obj.object, field, value)
                  yield obj
      except GeneratorExit:
          raise
  
Fix for de-serialization. Using vanilla django-money, when one did the following:
## Code Before:

import json
from decimal import Decimal

from django.core.serializers.python import Deserializer as PythonDeserializer
from django.core.serializers.json import Serializer as JSONSerializer
from django.core.serializers.python import _get_model
from django.utils import six

from djmoney.models.fields import MoneyField

Serializer = JSONSerializer


def Deserializer(stream_or_string, **options):
    """
    Deserialize a stream or string of JSON data.
    """
    if not isinstance(stream_or_string, (bytes, six.string_types)):
        stream_or_string = stream_or_string.read()
    if isinstance(stream_or_string, bytes):
        stream_or_string = stream_or_string.decode('utf-8')
    try:
        obj_list = []
        for obj in json.loads(stream_or_string):
            money_fields = {}
            fields = {}
            Model = _get_model(obj["model"])
            for (field_name, field_value) in obj['fields'].iteritems():
                field = Model._meta.get_field(field_name)
                if isinstance(field, MoneyField):
                    money_fields[field_name] = Decimal(
                        field_value.split(" ")[0])
                else:
                    fields[field_name] = field_value
            obj['fields'] = fields

            for obj in PythonDeserializer([obj], **options):
                for field, value in money_fields.items():
                    setattr(obj.object, field, value)
                yield obj
    except GeneratorExit:
        raise

## Instruction:
Fix for de-serialization. Using vanilla django-money, when one did the following:
## Code After:

import json
from decimal import Decimal

from django.core.serializers.python import Deserializer as PythonDeserializer
from django.core.serializers.json import Serializer as JSONSerializer
from django.core.serializers.python import _get_model
from django.utils import six

from djmoney.models.fields import MoneyField
from moneyed import Money

Serializer = JSONSerializer


def Deserializer(stream_or_string, **options):
    """
    Deserialize a stream or string of JSON data.
    """
    if not isinstance(stream_or_string, (bytes, six.string_types)):
        stream_or_string = stream_or_string.read()
    if isinstance(stream_or_string, bytes):
        stream_or_string = stream_or_string.decode('utf-8')
    try:
        obj_list = []
        for obj in json.loads(stream_or_string):
            money_fields = {}
            fields = {}
            Model = _get_model(obj["model"])
            for (field_name, field_value) in obj['fields'].iteritems():
                field = Model._meta.get_field(field_name)
                if isinstance(field, MoneyField):
                    money_fields[field_name] = Money(field_value, obj['fields']['%s_currency' % field_name])
                else:
                    fields[field_name] = field_value
            obj['fields'] = fields

            for obj in PythonDeserializer([obj], **options):
                for field, value in money_fields.items():
                    setattr(obj.object, field, value)
                yield obj
    except GeneratorExit:
        raise
