mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-10-31 07:57:55 +03:00 
			
		
		
		
	Merge pull request #311 from j4mie/fix-reverse-relations
Fix serialization of reverse relationships
This commit is contained in:
		
						commit
						bf06f0346a
					
				|  | @ -247,6 +247,19 @@ class BaseSerializer(Field): | ||||||
|         if not self._errors: |         if not self._errors: | ||||||
|             return self.restore_object(attrs, instance=getattr(self, 'object', None)) |             return self.restore_object(attrs, instance=getattr(self, 'object', None)) | ||||||
| 
 | 
 | ||||||
|  |     def field_to_native(self, obj, field_name): | ||||||
|  |         """ | ||||||
|  |         Override default so that we can apply ModelSerializer as a nested | ||||||
|  |         field to relationships. | ||||||
|  |         """ | ||||||
|  |         obj = getattr(obj, self.source or field_name) | ||||||
|  | 
 | ||||||
|  |         # If the object has an "all" method, assume it's a relationship | ||||||
|  |         if is_simple_callable(getattr(obj, 'all', None)): | ||||||
|  |             return [self.to_native(item) for item in obj.all()] | ||||||
|  | 
 | ||||||
|  |         return self.to_native(obj) | ||||||
|  | 
 | ||||||
|     @property |     @property | ||||||
|     def errors(self): |     def errors(self): | ||||||
|         """ |         """ | ||||||
|  | @ -295,16 +308,6 @@ class ModelSerializer(Serializer): | ||||||
|     """ |     """ | ||||||
|     _options_class = ModelSerializerOptions |     _options_class = ModelSerializerOptions | ||||||
| 
 | 
 | ||||||
|     def field_to_native(self, obj, field_name): |  | ||||||
|         """ |  | ||||||
|         Override default so that we can apply ModelSerializer as a nested |  | ||||||
|         field to relationships. |  | ||||||
|         """ |  | ||||||
|         obj = getattr(obj, self.source or field_name) |  | ||||||
|         if obj.__class__.__name__ in ('RelatedManager', 'ManyRelatedManager'): |  | ||||||
|             return [self.to_native(item) for item in obj.all()] |  | ||||||
|         return self.to_native(obj) |  | ||||||
| 
 |  | ||||||
|     def default_fields(self, serialize, obj=None, data=None, nested=False): |     def default_fields(self, serialize, obj=None, data=None, nested=False): | ||||||
|         """ |         """ | ||||||
|         Return all the fields that should be serialized for the model. |         Return all the fields that should be serialized for the model. | ||||||
|  |  | ||||||
|  | @ -92,6 +92,17 @@ class Comment(RESTFrameworkModel): | ||||||
|     content = models.CharField(max_length=200) |     content = models.CharField(max_length=200) | ||||||
|     created = models.DateTimeField(auto_now_add=True) |     created = models.DateTimeField(auto_now_add=True) | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| class ActionItem(RESTFrameworkModel): | class ActionItem(RESTFrameworkModel): | ||||||
|     title = models.CharField(max_length=200) |     title = models.CharField(max_length=200) | ||||||
|     done = models.BooleanField(default=False) |     done = models.BooleanField(default=False) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # Models for reverse relations | ||||||
|  | class BlogPost(RESTFrameworkModel): | ||||||
|  |     title = models.CharField(max_length=100) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class BlogPostComment(RESTFrameworkModel): | ||||||
|  |     text = models.TextField() | ||||||
|  |     blog_post = models.ForeignKey(BlogPost) | ||||||
|  |  | ||||||
|  | @ -302,3 +302,32 @@ class CallableDefaultValueTests(TestCase): | ||||||
|         self.assertEquals(len(self.objects.all()), 1) |         self.assertEquals(len(self.objects.all()), 1) | ||||||
|         self.assertEquals(instance.pk, 1) |         self.assertEquals(instance.pk, 1) | ||||||
|         self.assertEquals(instance.text, 'overridden') |         self.assertEquals(instance.text, 'overridden') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ManyRelatedTests(TestCase): | ||||||
|  |     def setUp(self): | ||||||
|  | 
 | ||||||
|  |         class BlogPostCommentSerializer(serializers.Serializer): | ||||||
|  |             text = serializers.CharField() | ||||||
|  | 
 | ||||||
|  |         class BlogPostSerializer(serializers.Serializer): | ||||||
|  |             title = serializers.CharField() | ||||||
|  |             comments = BlogPostCommentSerializer(source='blogpostcomment_set') | ||||||
|  | 
 | ||||||
|  |         self.serializer_class = BlogPostSerializer | ||||||
|  | 
 | ||||||
|  |     def test_reverse_relations(self): | ||||||
|  |         post = BlogPost.objects.create(title="Test blog post") | ||||||
|  |         post.blogpostcomment_set.create(text="I hate this blog post") | ||||||
|  |         post.blogpostcomment_set.create(text="I love this blog post") | ||||||
|  | 
 | ||||||
|  |         serializer = self.serializer_class(instance=post) | ||||||
|  |         expected = { | ||||||
|  |             'title': 'Test blog post', | ||||||
|  |             'comments': [ | ||||||
|  |                 {'text': 'I hate this blog post'}, | ||||||
|  |                 {'text': 'I love this blog post'} | ||||||
|  |             ] | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         self.assertEqual(serializer.data, expected) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user