Reputation: 155
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.
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
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
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
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