Question

I have a Complex Django model with (1) alot of fields and (2) dynamically generated data for this model that is not stored on the model.

Comlex Resource:

class ComplexResource(resource):
    class Meta:
        allowed_methods = ('get','put','post','delete','patch')
        queryset = Complex.objects.all()
        serializer = CustomSerializer()
        authorization = Authorization()
        authentication = Authentication()
        always_return_data  = True
        filtering = { "field_1" : ALL, "field_2" : ALL, "field_N" : ALL }
        ordering = ["field_1", "field_2", "field_n"]

Currently, my Complex endpoint /m/api/v1/complex/ successfully returns STORED data on the model.

Complex Response:

{   "meta": {
        "limit": 20,
        "next": null,
        "offset": 0,
        "previous": null,
        "total_count": 1
    },
    "objects": [
        {"field_1": "foo", "field_2": "bar", ... , "field_n": "foobar"}
    ]
}

Problem:

What I would like to do is to use prepend_urls to add a custom endpoint which will return all of the data. This way I wouldn't have to use dehydrate wastefully adding data every time I called my current endpoint which can be seen here:

http://django-tastypie.readthedocs.org/en/latest/cookbook.html#adding-custom-values

Question

How do I go about creating a prepend_url which injects additional data into a resource? or is there a better design pattern for solving this altogether?

Complex Response w/all data: /m/api/v1/complex/all/

{   "meta": {
        "limit": 20,
        "next": null,
        "offset": 0,
        "previous": null,
        "total_count": 1
    },
    "objects": [
        {"field_1": "foo",
         "field_2": "bar",
          .
          .
          . 
         "field_n": "foobar",
         "advanced_field_1 : "a1",
         "advanced_field_2 : "a2",
          . 
          . 
          . 
         "advanced_field_n : "an",
        }
    ]
}
Was it helpful?

Solution

I think dehydrate was made for cases like yours. Add query set argument to determine that dehydrate should compute addition fields or not.

def dehydrate(self, bundle):
    if bundle.request.GET.get('attach_dynamic_fields'):
        bundle.data['my_dynamic_field_1'] = make_dynamic_field(1)
        bundle.data['my_dynamic_field_2'] = make_dynamic_field(2)
    return bundle

Then just use when needed:

/api/v1/complex/ # Gives all, no dynamic fields attached

/api/v1/complex/1/ # Gives one, no dynamic fields attached

/api/v1/complex/?attach_dynamic_fields=1 # Gives all, with dynamic fields

/api/v1/complex/1/?attach_dynamic_fields=1 # Gives one, with dynamic fields

Creating prepend_url doesn't make sense for me. Because it means rewriting Tastypie again. Which is sign that something here is not RESTful.

If you want to do it anyway you should take a look on dispatch method and its flow: Flow through request / response cycle

You will have to rewrite this: dispatch method in your prepend_url somehow.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top