Instantly share code, notes, and snippets.

@guglielmo /places.py
Last active Dec 30, 2015

Embed
What would you like to do?
Code to reproduce a probable issue within django-rest-framework. A Place may have many acronyms. The reverse fk relationship ('acronyms') is serialized with a nested AcronymSerializer. When issuing PUT to edit the place, the old acronyms not in the json payload anymore, are not removed from the DB. The HTML form shows the error: non_field_errors…
## Models
class Place(models.Model):
name = models.CharField(max_length=255, blank=True)
slug = models.SlugField(max_length=255, null=True, blank=True)
class PlaceAcronym(models.Model):
place = models.ForeignKey('Place', related_name="acronyms")
acronym = models.CharField(_("acronym"), max_length=128,
help_text=_("An acronym for the place, e.g. 'PV'")
)
## Detail View
class PlaceDetail(generics.RetrieveUpdateDestroyAPIView):
model = Place
serializer_class = PlaceSerializer
## Serializers
class AcronymSerializer(serializers.ModelSerializer):
def get_identity(self, data):
return data
def to_native(self, value):
return '%s' % (value.acronym, )
def from_native(self, data, files):
value = super(AcronymSerializer, self).from_native({'acronym': data}, files)
return value
class Meta:
model = PlaceAcronym
fields = ('acronym',)
class PlaceSerializer(serializers.ModelSerializer):
acronyms = AcronymSerializer(many=True, allow_add_remove=True)
class Meta:
model = Place
view_name = 'maps:place-detail'
lookup_field = 'slug'
_self = serializers.HyperlinkedIdentityField(view_name='maps:place-detail')
fields = (
'_self',
'slug', 'name', 'acronyms',
)
@guglielmo

This comment has been minimized.

Show comment
Hide comment
@guglielmo

guglielmo Dec 8, 2013

Acronyms are not specified by ID, so the AcronymSerializer needs to override the get_identity hook, and use

return data.get('acronym', None)

instead of

return data.get('id', None)
Owner

guglielmo commented Dec 8, 2013

Acronyms are not specified by ID, so the AcronymSerializer needs to override the get_identity hook, and use

return data.get('acronym', None)

instead of

return data.get('id', None)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment