mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-11-04 09:57:55 +03:00 
			
		
		
		
	Merge pull request #1527 from Ian-Foote/generic_foreign_key
Set GenericForeignKey fields on object before save
This commit is contained in:
		
						commit
						1d404874b3
					
				| 
						 | 
					@ -16,6 +16,7 @@ import datetime
 | 
				
			||||||
import inspect
 | 
					import inspect
 | 
				
			||||||
import types
 | 
					import types
 | 
				
			||||||
from decimal import Decimal
 | 
					from decimal import Decimal
 | 
				
			||||||
 | 
					from django.contrib.contenttypes.generic import GenericForeignKey
 | 
				
			||||||
from django.core.paginator import Page
 | 
					from django.core.paginator import Page
 | 
				
			||||||
from django.db import models
 | 
					from django.db import models
 | 
				
			||||||
from django.forms import widgets
 | 
					from django.forms import widgets
 | 
				
			||||||
| 
						 | 
					@ -943,6 +944,8 @@ class ModelSerializer(Serializer):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Forward m2m relations
 | 
					        # Forward m2m relations
 | 
				
			||||||
        for field in meta.many_to_many + meta.virtual_fields:
 | 
					        for field in meta.many_to_many + meta.virtual_fields:
 | 
				
			||||||
 | 
					            if isinstance(field, GenericForeignKey):
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
            if field.name in attrs:
 | 
					            if field.name in attrs:
 | 
				
			||||||
                m2m_data[field.name] = attrs.pop(field.name)
 | 
					                m2m_data[field.name] = attrs.pop(field.name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -952,17 +955,15 @@ class ModelSerializer(Serializer):
 | 
				
			||||||
            if isinstance(self.fields.get(field_name, None), Serializer):
 | 
					            if isinstance(self.fields.get(field_name, None), Serializer):
 | 
				
			||||||
                nested_forward_relations[field_name] = attrs[field_name]
 | 
					                nested_forward_relations[field_name] = attrs[field_name]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Update an existing instance...
 | 
					        # Create an empty instance of the model
 | 
				
			||||||
        if instance is not None:
 | 
					        if instance is None:
 | 
				
			||||||
            for key, val in attrs.items():
 | 
					            instance = self.opts.model()
 | 
				
			||||||
                try:
 | 
					 | 
				
			||||||
                    setattr(instance, key, val)
 | 
					 | 
				
			||||||
                except ValueError:
 | 
					 | 
				
			||||||
                    self._errors[key] = self.error_messages['required']
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # ...or create a new instance
 | 
					        for key, val in attrs.items():
 | 
				
			||||||
        else:
 | 
					            try:
 | 
				
			||||||
            instance = self.opts.model(**attrs)
 | 
					                setattr(instance, key, val)
 | 
				
			||||||
 | 
					            except ValueError:
 | 
				
			||||||
 | 
					                self._errors[key] = self.error_messages['required']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Any relations that cannot be set until we've
 | 
					        # Any relations that cannot be set until we've
 | 
				
			||||||
        # saved the model get hidden away on these
 | 
					        # saved the model get hidden away on these
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -131,3 +131,21 @@ class TestGenericRelations(TestCase):
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
        self.assertEqual(serializer.data, expected)
 | 
					        self.assertEqual(serializer.data, expected)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_restore_object_generic_fk(self):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Ensure an object with a generic foreign key can be restored.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class TagSerializer(serializers.ModelSerializer):
 | 
				
			||||||
 | 
					            class Meta:
 | 
				
			||||||
 | 
					                model = Tag
 | 
				
			||||||
 | 
					                exclude = ('content_type', 'object_id')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        serializer = TagSerializer()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        bookmark = Bookmark(url='http://example.com')
 | 
				
			||||||
 | 
					        attrs = {'tagged_item': bookmark, 'tag': 'example'}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        tag = serializer.restore_object(attrs)
 | 
				
			||||||
 | 
					        self.assertEqual(tag.tagged_item, bookmark)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user