Derek
Derek

Reputation: 12378

Get model object from tastypie uri?

How do you get the model object of a tastypie modelresource from it's uri?

for example:

if you were given the uri as a string in python, how do you get the model object of that string?

Upvotes: 5

Views: 3823

Answers (3)

Jonathan Potter
Jonathan Potter

Reputation: 3081

You can use get_via_uri, but as @Zakum mentions, that will apply authorization, which you probably don't want. So digging into the source for that method we see that we can resolve the URI like this:

from django.core.urlresolvers import resolve, get_script_prefix

def get_pk_from_uri(uri):
    prefix = get_script_prefix()
    chomped_uri = uri

    if prefix and chomped_uri.startswith(prefix):
        chomped_uri = chomped_uri[len(prefix)-1:]

    try:
        view, args, kwargs = resolve(chomped_uri)
    except Resolver404:
        raise NotFound("The URL provided '%s' was not a link to a valid resource." % uri)

    return kwargs['pk']

If your Django application is located at the root of the webserver (i.e. get_script_prefix() == '/') then you can simplify this down to:

view, args, kwargs = resolve(uri)
pk = kwargs['pk']

Upvotes: 2

Zakum
Zakum

Reputation: 2287

Tastypie's Resource class (which is the guy ModelResource is subclassing ) provides a method get_via_uri(uri, request). Be aware that his calls through to apply_authorization_limits(request, object_list) so if you don't receive the desired result make sure to edit your request in such a way that it passes your authorisation.

A bad alternative would be using a regex to extract the id from your url and then use it to filter through the list of all objects. That was my dirty hack until I got get_via_uri working and I do NOT recommend using this. ;)

id_regex = re.compile("/(\d+)/$")
object_id = id_regex.findall(your_url)[0]
your_object = filter(lambda x: x.id == int(object_id),YourResource().get_object_list(request))[0]

Upvotes: 2

Hedde van der Heide
Hedde van der Heide

Reputation: 22449

Are you looking for the flowchart? It really depends on when you want the object.

Within the dehydration cycle you simple can access it via bundle, e.g.

class MyResource(Resource):
    # fields etc.

    def dehydrate(self, bundle):
        # Include the request IP in the bundle if the object has an attribute value
        if bundle.obj.user:
            bundle.data['request_ip'] = bundle.request.META.get('REMOTE_ADDR')
        return bundle

If you want to manually retrieve an object by an api url, given a pattern you could simply traverse the slug or primary key (or whatever it is) via the default orm scheme?

Upvotes: 1

Related Questions