Vincent Alvo
Vincent Alvo

Reputation: 155

Django REST framework, get object from URL

I'm wondering if there is a clean way to retrieve an object from its URL with django rest framework. Surely there should be, as it seems to be what's happening when using HyperlinkedRelatedField.

For instance, I have this URL /api/comment/26 as a string. From my view, how can I get the comment instance with pk=26?

Of course I could redo the work and work on the string but it must be a better way?

Thanks a lot.

EDIT:

This is how I solved it at the end:

resolve('/api/comment/26/').func.cls.model will return my model Comment. resolve('/api/category/1/').kwargs['pk'] will return the pk.

Which gives you:

from django.core.urlresolvers import resolve

resolved_func, unused_args, resolved_kwargs = resolve('/api/category/1/')
resolved_func.cls.model.objects.get(pk=resolved_kwargs['pk'])

Upvotes: 6

Views: 5850

Answers (3)

Pinna_be
Pinna_be

Reputation: 4617

Solution above did not work for me, the following did work though:

from django.core.urlresolvers import resolve

resolved_func, unused_args, resolved_kwargs = resolve('/api/category/1/')
resolved_func.cls().get_queryset().get(id=resolved_kwargs['pk'])

additionally this solution uses the built in queryset of your view, which might have annotations or important filters.

Using HyperlinkedModelSerializer I actually needed to do this with a full url. For this to work, you need to extract the path first, resulting in:

import urllib.parse
from django.core.urlresolvers import resolve

def obj_from_url(url):
    path = urllib.parse.urlparse(url).path
    resolved_func, unused_args, resolved_kwargs = resolve(path)
    return resolved_func.cls().get_queryset().get(id=resolved_kwargs['pk'])

Upvotes: 0

piro
piro

Reputation: 13931

With class-based views, something like the following seems needed:

resolve(url).func.cls.serializer_class.Meta.model.objects.get(
    **resolve(url).kwargs)

Upvotes: 2

Carlton Gibson
Carlton Gibson

Reputation: 7386

I suspect your best bet would be to manually keep a map of models to url patterns — not too dissimilar from a URLConf.

If that doesn't rock your boat you could pass the path into resolve.

This will give you a ResolverMatch upon which you'll find the func that was returned by the as_view call when you set up your URLs.

The __name__ attribute of your view function will be that of your original view class. Do something like globals()[class_name] to get the class itself.

From there access the model attribute.

I hope that helps. As I say, you might just want to map models to URLs yourself.

Upvotes: 3

Related Questions