Code

Ticket #9522: 9522.patch

File 9522.patch, 3.8 KB (added by alexkoshelev, 5 years ago)

new patch with tests

  • django/db/models/fields/__init__.py

     
    5252    # Designates whether empty strings fundamentally are allowed at the 
    5353    # database level. 
    5454    empty_strings_allowed = True 
     55     
     56    # Designates whether this field's value must be converted to string 
     57    # by `value_to_string` method while serialization 
     58    serialize_to_string = False 
    5559 
    5660    # These track each time a Field instance is created. Used to retain order. 
    5761    # The auto_creation_counter is used for fields that Django implicitly 
  • django/core/serializers/python.py

     
    3535        self._current = None 
    3636 
    3737    def handle_field(self, obj, field): 
    38         self._current[field.name] = smart_unicode(getattr(obj, field.name), strings_only=True) 
     38        if field.serialize_to_string: 
     39            value = self.get_string_value(obj, field) 
     40        else: 
     41            value = smart_unicode(getattr(obj, field.name), strings_only=True) 
     42        self._current[field.name] = value 
    3943 
    4044    def handle_fk_field(self, obj, field): 
    4145        related = getattr(obj, field.name) 
  • tests/modeltests/serializers/models.py

     
    6767class Score(models.Model): 
    6868    score = models.FloatField() 
    6969 
     70 
     71class Team(object): 
     72    def __init__(self, title): 
     73        self.title = title 
     74         
     75    def __unicode__(self): 
     76        raise NotImplementedError("Not so simple") 
     77     
     78    def __str__(self): 
     79        raise NotImplementedError("Not so simple") 
     80     
     81    def to_string(self): 
     82        return "%s" % self.title 
     83     
     84class TeamField(models.CharField): 
     85    __metaclass__ = models.SubfieldBase 
     86     
     87    serialize_to_string = True 
     88     
     89    def __init__(self): 
     90        super(TeamField, self).__init__(max_length=100) 
     91     
     92    def get_db_prep_save(self, value): 
     93        return unicode(value.title) 
     94     
     95    def to_python(self, value): 
     96        if isinstance(value, Team): 
     97            return value 
     98        return Team(value) 
     99     
     100    def value_to_string(self, obj): 
     101        return self._get_val_from_obj(obj).to_string() 
     102     
     103class Player(models.Model): 
     104    rank = models.IntegerField() 
     105    team = TeamField() 
     106     
     107    def __unicode__(self): 
     108        return self.team.to_string() 
     109 
    70110__test__ = {'API_TESTS':""" 
    71111# Create some data: 
    72112>>> from datetime import datetime 
     
    217257>>> print list(serializers.deserialize('json', serializers.serialize('json', [sc])))[0].object.score 
    2182583.4 
    219259 
     260 
     261# Custom field with non trivial to string convertion value 
     262>>> player = Player() 
     263>>> player.rank = 1 
     264>>> player.team = Team("Spartak Moskva") 
     265>>> player.save() 
     266 
     267>>> serialized =  serializers.serialize("json", Player.objects.all()) 
     268>>> print serialized 
     269[{"pk": 1, "model": "serializers.player", "fields": {"rank": 1, "team": "Spartak Moskva"}}] 
     270 
     271>>> obj = list(serializers.deserialize("yaml", serialized))[0] 
     272>>> print obj 
     273<DeserializedObject: Spartak Moskva> 
    220274"""} 
    221275 
    222276try: 
     
    253307<DeserializedObject: Just kidding; I love TV poker> 
    254308<DeserializedObject: Time to reform copyright> 
    255309 
     310# Custom field with non trivial to string convertion value with YAML serializer 
     311 
     312>>> print serializers.serialize("yaml", Player.objects.all()) 
     313- fields: {rank: 1, team: Spartak Moskva} 
     314  model: serializers.player 
     315  pk: 1 
     316<BLANKLINE> 
     317 
    256318""" 
    257319except ImportError: 
    258320    pass