Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support multiple parametersfor Hyperlinked fields? #1024

Closed
millarm opened this issue Aug 4, 2013 · 7 comments
Closed

Support multiple parametersfor Hyperlinked fields? #1024

millarm opened this issue Aug 4, 2013 · 7 comments

Comments

@millarm
Copy link

millarm commented Aug 4, 2013

I'd really like to be able to reverse hyperlinked URLs on more than just one field, and with fields that span across models.

So I'd love to have a "lookup_fields" parameter - that behaves like this:

Better HyperlinkedIdentityField

from rest_framework.relations import HyperlinkedIdentityField
from rest_framework.reverse import reverse

class ParameterisedHyperlinkedIdentityField(HyperlinkedIdentityField):
    """
    Represents the instance, or a property on the instance, using hyperlinking.

    lookup_fields is a tuple of tuples of the form:
        ('model_field', 'url_parameter')
    """
    lookup_fields = (('pk', 'pk'),)

    def __init__(self, *args, **kwargs):
        self.lookup_fields = kwargs.pop('lookup_fields', self.lookup_fields)
        super(ParameterisedHyperlinkedIdentityField, self).__init__(*args, **kwargs)

    def get_url(self, obj, view_name, request, format):
        """
        Given an object, return the URL that hyperlinks to the object.

        May raise a `NoReverseMatch` if the `view_name` and `lookup_field`
        attributes are not configured to correctly match the URL conf.
        """
        kwargs = {}
        for model_field, url_param in self.lookup_fields:
            attr = obj
            for field in model_field.split('.'):
                attr = getattr(attr,field)
            kwargs[url_param] = attr

        try:
            return reverse(view_name, kwargs=kwargs, request=request, format=format)
        except NoReverseMatch:
            pass

        raise NoReverseMatch()
@millarm
Copy link
Author

millarm commented Aug 4, 2013

this lets me do things like:

vote_url = ParameterisedHyperlinkedIdentityField(
    view_name="vote", lookup_fields=(('poll.id', 'poll_id'), ('id', 'choice_id')))

where the urlscheme has <poll_id> and <choice_id> and the Choice object has a Foreign Key to a poll object

@tomchristie
Copy link
Member

Related: https://groups.google.com/forum/#!searchin/django-rest-framework/relevant$20key/django-rest-framework/rNGOVUAIv9Q/J2io9Nfvc74J

Also related: http://django-rest-framework.org/api-guide/generic-views.html#creating-custom-mixins

I would love to see someone write a good third party package that properly deals with this, but I don't want to have to maintain it in core (there's already plenty of maintaince overhead on the project). I think this needs to be covered both by a custom hyperlinked relational field, that accepts lookup_fields instead of lookup_field, a view mixin that does the same, and ideally also a router or router mixin that'd deal with automatically routing viewsets using lookup_fields - there's plenty of work there for a good useful 3rd party package, and would absolutely want to link to that from the main docs if you or someone else wants to take it on.

Like I say though it's not something I'm willing to take on in core right now. I do think it'd be super useful to have, but there's no reason it can't be handled as a seperate package.

@millarm
Copy link
Author

millarm commented Aug 15, 2013

Tom,

Is there a wiki with details of third party packages?

We've already created and tested the first part if this, and may be
motivated to do the latter parts & package and push back out for the
community.

Matt

On Thursday, August 15, 2013, Tom Christie wrote:

Related:
https://groups.google.com/forum/#!searchin/django-rest-framework/relevant$20key/django-rest-framework/rNGOVUAIv9Q/J2io9Nfvc74J

Also related:
http://django-rest-framework.org/api-guide/generic-views.html#creating-custom-mixins

I would love to see someone write a good third party package that properly
deals with this, but I don't want to have to maintain it in core (there's
already plenty of maintaince overhead on the project). I think this needs
to be covered both by a custom hyperlinked relational field, that accepts
lookup_fields instead of lookup_field, a view mixin that does the same,
and ideally also a router or router mixin that'd deal with automatically
routing viewsets using lookup_fields - there's plenty of work there for a
good useful 3rd party package, and would absolutely want to link to that
from the main docs if you or someone else wants to take it on.

Like I say though it's not something I'm willing to take on in core right
now. I do think it'd be super useful to have, but there's no reason it
can't be handled as a seperate package.


Reply to this email directly or view it on GitHubhttps://github.com//issues/1024#issuecomment-22725178
.

@tomchristie
Copy link
Member

@millarm - We can either link to it from appropriate parts of the docs (eg see the '3rd party packages' sections at the end of various parts of the docs, such as authentication). There's also this #1019 which I guess needs a bit more fleshing out but should hopefully get pulled in.

@tomchristie
Copy link
Member

(In particular I guess we'd link to it from the serializer relations docs and possibly also generic views docs, dep on what your package covers exactly)

@bkovacev
Copy link

@millarm @tomchristie I was actually looking for something like this and it works as provided by millarm. One question - do you plan to support this in the future?

@tomchristie
Copy link
Member

@bkovacev Not planned no - folks tie themselves up in knots with Hyperlinked fields as it is - supporting multiple lookups in the core REST framework would only make that worse. Much more keen to have it as a third party package that we could link too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants