Django Rest Framework, HyperlinkedModelSerializers, ModelViewSets, and writable GenericForeignKeys: how? -
Django Rest Framework, HyperlinkedModelSerializers, ModelViewSets, and writable GenericForeignKeys: how? -
i've got model financialtransaction
has typical content_type
, object_id
, , content_object
fields set generic relations of other models.
i've figured out how serialize relation reading:
class financialtransactionserializer(serializers.hyperlinkedmodelserializer): content_object = serializers.serializermethodfield('get_content_obj_url') def get_content_obj_url(self, obj): obj = obj.content_object view_name = obj._meta.object_name.lower() + "-detail" s = serializers.hyperlinkedidentityfield(source=obj, view_name=view_name) s.initialize(self, none) homecoming s.field_to_native(obj, none) class meta: model = financialtransaction fields = ('id', 'value', 'date', 'memo', 'banking_account', 'content_object')
the viewset:
class financialtransactionviewset(viewsets.modelviewset): model = financialtransaction serializer_class = financialtransactionserializer
this creates hyperlink related object serialized representation when on view.
however, i'm kind of stuck on how create can post new financialtransaction existing related object.
ideally, work normal foreignkey can post like:
{"value": "200.00", "date": "2014-10-10", "memo": "repairs", "banking_account": "http://domain.com/api/banking_account/134/", "content_object": "http://domain.com/api/property/432/" }
ok, reply own question...
i overrode restore_fields
in own serializer this:
class financialtransactionserializer(serializers.hyperlinkedmodelserializer): content_object = serializers.serializermethodfield('get_content_obj_url') def get_content_obj_url(self, obj): obj = obj.content_object view_name = get_view_name(obj) s = serializers.hyperlinkedidentityfield(source=obj, view_name=view_name) s.initialize(self, none) homecoming s.field_to_native(obj, none) def restore_fields(self, data, files): content_object = none if 'content_object' in data: request = self.context.get('request') content_object = get_object_from_url(request.data['content_object']) attrs = super(financialtransactionserializer, self).restore_fields(data, files) if content_object: attrs['content_object'] = content_object homecoming attrs class meta: model = financialtransaction fields = ('id', 'value', 'date', 'memo', 'banking_account', 'content_object') def get_model_from_url(url: str): homecoming resolve(urlparse(url).path).func.cls.model def get_object_from_url(url: str): model = get_model_from_url(url) pk = resolve(urlparse(url).path).kwargs.get('pk') if not pk: homecoming none homecoming model.objects.get(pk=pk)
this setup serializes objects content_object
field contains hyperlink related object, , when post'ing view using serializer, , info includes content_object
key, related object , pass on.
the attrs returned restore_fields
used in restore_object
method, , since looked content object , set in attrs, restore_object
sets content_object
attribute on financialtransaction object retrieved object , django takes care of rest.
so far downside can see doesn't add together content_object
field browsable api...but i'm not sure how that'd work anyway since related objects provided in select, , don't think we'd want select populated every single object in our database.
django django-rest-framework
Comments
Post a Comment