mirror of
				https://github.com/django/django.git
				synced 2025-11-04 05:35:37 +00:00 
			
		
		
		
	Fixed #3466 -- Fixed problem with specifyin a 'fields' argument to a JSON serializer. Also added documenation for the 'fields' argument.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5409 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
		
							parent
							
								
									8728e0f353
								
							
						
					
					
						commit
						ea07351799
					
				
					 6 changed files with 73 additions and 0 deletions
				
			
		| 
						 | 
					@ -21,6 +21,8 @@ class Serializer(PythonSerializer):
 | 
				
			||||||
    Convert a queryset to JSON.
 | 
					    Convert a queryset to JSON.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    def end_serialization(self):
 | 
					    def end_serialization(self):
 | 
				
			||||||
 | 
					        self.options.pop('stream', None)
 | 
				
			||||||
 | 
					        self.options.pop('fields', None)
 | 
				
			||||||
        simplejson.dump(self.objects, self.stream, cls=DjangoJSONEncoder, **self.options)
 | 
					        simplejson.dump(self.objects, self.stream, cls=DjangoJSONEncoder, **self.options)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def getvalue(self):
 | 
					    def getvalue(self):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,6 +18,8 @@ class Serializer(PythonSerializer):
 | 
				
			||||||
    Convert a queryset to YAML.
 | 
					    Convert a queryset to YAML.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    def end_serialization(self):
 | 
					    def end_serialization(self):
 | 
				
			||||||
 | 
					        self.options.pop('stream', None)
 | 
				
			||||||
 | 
					        self.options.pop('fields', None)
 | 
				
			||||||
        yaml.dump(self.objects, self.stream, **self.options)
 | 
					        yaml.dump(self.objects, self.stream, **self.options)
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    def getvalue(self):
 | 
					    def getvalue(self):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,6 +44,25 @@ This is useful if you want to serialize data directly to a file-like object
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. _HTTPResponse: ../request_response/#httpresponse-objects
 | 
					.. _HTTPResponse: ../request_response/#httpresponse-objects
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Subset of fields
 | 
				
			||||||
 | 
					~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you only want a subset of fields to be serialized, you can 
 | 
				
			||||||
 | 
					specify a `fields` argument to the serializer::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    from django.core import serializers
 | 
				
			||||||
 | 
					    data = serializers.serialize('xml', SomeModel.objects.all(), fields=('name','size'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In this example, only the `name` and `size` attributes of each model will
 | 
				
			||||||
 | 
					be serialized. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. note::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Depending on your model, you may find that it is not possible to deserialize
 | 
				
			||||||
 | 
					    a model that only serializes a subset of it's fields. If a serialized object
 | 
				
			||||||
 | 
					    doesn't specify all the fields that are required by a model, the deserializer
 | 
				
			||||||
 | 
					    will not be able to save deserialized instances.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Deserializing data
 | 
					Deserializing data
 | 
				
			||||||
------------------
 | 
					------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -92,10 +111,15 @@ Django "ships" with a few included serializers:
 | 
				
			||||||
    ``python``  Translates to and from "simple" Python objects (lists, dicts,
 | 
					    ``python``  Translates to and from "simple" Python objects (lists, dicts,
 | 
				
			||||||
                strings, etc.).  Not really all that useful on its own, but
 | 
					                strings, etc.).  Not really all that useful on its own, but
 | 
				
			||||||
                used as a base for other serializers.
 | 
					                used as a base for other serializers.
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ``yaml``    Serializes to YAML (Yet Another Markup Lanuage). This 
 | 
				
			||||||
 | 
					                serializer will only be made available if PyYAML_ is installed.
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
    ==========  ==============================================================
 | 
					    ==========  ==============================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. _json: http://json.org/
 | 
					.. _json: http://json.org/
 | 
				
			||||||
.. _simplejson: http://undefined.org/python/#simplejson
 | 
					.. _simplejson: http://undefined.org/python/#simplejson
 | 
				
			||||||
 | 
					.. _PyYAML: http://www.pyyaml.org/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Notes for specific serialization formats
 | 
					Notes for specific serialization formats
 | 
				
			||||||
----------------------------------------
 | 
					----------------------------------------
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -159,4 +159,8 @@ __test__ = {'API_TESTS':"""
 | 
				
			||||||
>>> article.author
 | 
					>>> article.author
 | 
				
			||||||
<Author: Agnes>
 | 
					<Author: Agnes>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Serializer output can be restricted to a subset of fields
 | 
				
			||||||
 | 
					>>> print serializers.serialize("json", Article.objects.all(), fields=('headline','pub_date'))
 | 
				
			||||||
 | 
					[{"pk": "1", "model": "serializers.article", "fields": {"headline": "Just kidding; I love TV poker", "pub_date": "2006-06-16 11:00:00"}}, {"pk": "2", "model": "serializers.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": "3", "model": "serializers.article", "fields": {"headline": "Forward references pose no problem", "pub_date": "2006-06-16 15:00:00"}}]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"""}
 | 
					"""}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -205,3 +205,7 @@ class USStatePKData(models.Model):
 | 
				
			||||||
# class XMLPKData(models.Model):
 | 
					# class XMLPKData(models.Model):
 | 
				
			||||||
#     data = models.XMLField(primary_key=True)
 | 
					#     data = models.XMLField(primary_key=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ComplexModel(models.Model):
 | 
				
			||||||
 | 
					    field1 = models.CharField(maxlength=10)
 | 
				
			||||||
 | 
					    field2 = models.CharField(maxlength=10)
 | 
				
			||||||
 | 
					    field3 = models.CharField(maxlength=10)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,7 @@ forward, backwards and self references.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import unittest, datetime
 | 
					import unittest, datetime
 | 
				
			||||||
 | 
					from cStringIO import StringIO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.utils.functional import curry
 | 
					from django.utils.functional import curry
 | 
				
			||||||
from django.core import serializers
 | 
					from django.core import serializers
 | 
				
			||||||
| 
						 | 
					@ -278,5 +279,41 @@ def serializerTest(format, self):
 | 
				
			||||||
    for (func, pk, klass, datum) in test_data:
 | 
					    for (func, pk, klass, datum) in test_data:
 | 
				
			||||||
        func[1](self, pk, klass, datum)
 | 
					        func[1](self, pk, klass, datum)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def fieldsTest(format, self):
 | 
				
			||||||
 | 
					    # Clear the database first
 | 
				
			||||||
 | 
					    management.flush(verbosity=0, interactive=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    obj = ComplexModel(field1='first',field2='second',field3='third')
 | 
				
			||||||
 | 
					    obj.save()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Serialize then deserialize the test database
 | 
				
			||||||
 | 
					    serialized_data = serializers.serialize(format, [obj], indent=2, fields=('field1','field3'))
 | 
				
			||||||
 | 
					    result = serializers.deserialize(format, serialized_data).next()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Check that the deserialized object contains data in only the serialized fields.
 | 
				
			||||||
 | 
					    self.assertEqual(result.object.field1, 'first')
 | 
				
			||||||
 | 
					    self.assertEqual(result.object.field2, '')
 | 
				
			||||||
 | 
					    self.assertEqual(result.object.field3, 'third')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def streamTest(format, self):
 | 
				
			||||||
 | 
					    # Clear the database first
 | 
				
			||||||
 | 
					    management.flush(verbosity=0, interactive=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    obj = ComplexModel(field1='first',field2='second',field3='third')
 | 
				
			||||||
 | 
					    obj.save()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Serialize the test database to a stream
 | 
				
			||||||
 | 
					    stream = StringIO()    
 | 
				
			||||||
 | 
					    serializers.serialize(format, [obj], indent=2, stream=stream)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Serialize normally for a comparison
 | 
				
			||||||
 | 
					    string_data = serializers.serialize(format, [obj], indent=2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Check that the two are the same
 | 
				
			||||||
 | 
					    self.assertEqual(string_data, stream.buffer())
 | 
				
			||||||
 | 
					    stream.close()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
for format in serializers.get_serializer_formats():
 | 
					for format in serializers.get_serializer_formats():
 | 
				
			||||||
    setattr(SerializerTests, 'test_'+format+'_serializer', curry(serializerTest, format))
 | 
					    setattr(SerializerTests, 'test_'+format+'_serializer', curry(serializerTest, format))
 | 
				
			||||||
 | 
					    setattr(SerializerTests, 'test_'+format+'_serializer_fields', curry(fieldsTest, format))
 | 
				
			||||||
 | 
					    setattr(SerializerTests, 'test_'+format+'_serializer_stream', curry(fieldsTest, format))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue