Deal with reversed GenericFK.

This commit is contained in:
Xavier Ordoquy 2014-04-30 23:51:07 +02:00
parent 9f9ad964cd
commit 5dab5e4dcf

View File

@ -16,7 +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.contrib.contenttypes.generic import GenericForeignKey, GenericRelation
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
@ -932,6 +932,7 @@ class ModelSerializer(Serializer):
m2m_data = {} m2m_data = {}
related_data = {} related_data = {}
nested_forward_relations = {} nested_forward_relations = {}
generic_fk = []
meta = self.opts.model._meta meta = self.opts.model._meta
# Reverse fk or one-to-one relations # Reverse fk or one-to-one relations
@ -950,6 +951,8 @@ class ModelSerializer(Serializer):
for field in meta.many_to_many + meta.virtual_fields: for field in meta.many_to_many + meta.virtual_fields:
if isinstance(field, GenericForeignKey): if isinstance(field, GenericForeignKey):
continue continue
if isinstance(field, GenericRelation):
generic_fk.append(field.name)
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)
@ -973,6 +976,7 @@ class ModelSerializer(Serializer):
# saved the model get hidden away on these # saved the model get hidden away on these
# private attributes, so we can deal with them # private attributes, so we can deal with them
# at the point of save. # at the point of save.
instance._generic_fk = generic_fk
instance._related_data = related_data instance._related_data = related_data
instance._m2m_data = m2m_data instance._m2m_data = m2m_data
instance._nested_forward_relations = nested_forward_relations instance._nested_forward_relations = nested_forward_relations
@ -1003,9 +1007,13 @@ class ModelSerializer(Serializer):
if getattr(obj, '_m2m_data', None): if getattr(obj, '_m2m_data', None):
for accessor_name, object_list in obj._m2m_data.items(): for accessor_name, object_list in obj._m2m_data.items():
# We need to save m2m data before linking the objects together if accessor_name in getattr(obj, '_generic_fk', []):
[self.save_object(o) for o in object_list] # We are dealing with a reversed generic FK
setattr(obj, accessor_name, object_list) setattr(obj, accessor_name, object_list)
[self.save_object(o) for o in object_list if not isinstance(o, GenericRelation)]
if accessor_name not in getattr(obj, '_generic_fk', []):
# We need to save m2m data before linking the objects together
setattr(obj, accessor_name, object_list)
del(obj._m2m_data) del(obj._m2m_data)
if getattr(obj, '_related_data', None): if getattr(obj, '_related_data', None):