simpleenergy / django-rest-framework-nested-resource

A view mixin for DRF which simplifies nested resources.
Other
7 stars 4 forks source link

Extra DB Query? #5

Open cancan101 opened 10 years ago

cancan101 commented 10 years ago

It looks like you resolve the pk of the parent object here: https://github.com/simpleenergy/django-rest-framework-nested-resource/blob/19244a55aa67eef47c0db3381dd485729142dc50/drf_nested_resource/mixins.py#L43

and then insert the pk into the data passed to the serializer.

Presumably that pk is then looked up again over here: https://github.com/tomchristie/django-rest-framework/blob/d2795dd26d7483ea0de119ae135eab0a94cf23d8/rest_framework/relations.py#L219 ?

If that is the case (and it would be worth profiling the queries to see if it is), then is there some way to avoid this extra lookup?

pipermerriam commented 10 years ago

I actually think that the entire lookup of the parent object is not needed as if it does not exist, the error will be raised in the drf code you linked. I'm not 100% on this though, and I haven't fully thought through the implications of this change. I think making that modification and seeing what tests fail would be a good starting off point.

cancan101 commented 10 years ago

I solve it using something like: https://github.com/chibisov/drf-extensions/issues/15#issuecomment-58711880

I updated it to be:

class InjectFieldsMixin(object):
    def inject(self, init_data, field_name, kwarg_name):
        init_data[field_name] = self.kwargs[kwarg_name]

    def get_serializer(self, *args, **kwargs):
        parent = super(InjectFieldsMixin, self).get_serializer(*args, **kwargs)
        if hasattr(parent, 'init_data') and parent.init_data is not None:
            # For some reason when the init_data is empty, it is set to an immutable QueryDict
            # which causes problems with injection
            if len(parent.init_data) == 0 and isinstance(parent.init_data, django.http.request.QueryDict):
                parent.init_data = {}

            fields = parent.fields
            mapping = self.get_inject_field_map()
            for field_name, field in fields.iteritems():
                if field_name in mapping:
                    self.inject(parent.init_data, field_name, mapping[field_name])

with mapping something like you have here: https://github.com/simpleenergy/django-rest-framework-nested-resource/blob/19244a55aa67eef47c0db3381dd485729142dc50/drf_nested_resource/mixins.py#L45

cancan101 commented 10 years ago

get_queryset can likewise be done with a filter rather than needing the parent object. Something like: https://github.com/alanjds/drf-nested-routers/issues/7#issuecomment-41393500

kingsleytorlowei commented 5 years ago

Can you provide more context to how you implemented this? I know it's been almost 5 years but i have the same issue implement POST requests in nested relationships by posting just the foreign key.