Skip to content

HyperlinkedModelSerializer Does not Provide the Serializer we are Hyperlinking to. #483

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

Closed
pkkid opened this issue Dec 8, 2012 · 7 comments

Comments

@pkkid
Copy link
Contributor

pkkid commented Dec 8, 2012

HyperlinkedModelSerializer does not provide the serializer we are hyperlinking to. This means there is no programmable way to follow this relationship if navigating the the serializers via Python.

Why do I want to navigate the serializers? -- To build a generic filtering (search) mechanism for any API that includes to ability to filter on linked serializers. I can currently follow the relationships when we link to a serializer directly (not using the hyperlink classes). The serializer is there, I can reach in, grab the attributes I want to filter on and move on. However, I hit a wall when trying to do this in the other direction via HyperlinkedRelatedField, because the serializer isn't referenced anywhere.


There are three solutions to this problem that I can think of:

1.) Rather than having the HyperlinkedRelatedField take a view name, have it take a serializer reference and get the URL from the built in "url" field.

2.) Simply add another (maybe optional?) argument to HyperlinkedRelatedField that takes the serializer class allowing us to follow the chain.

3.) Same as number 2, but I make a subclass of HyperlinkedRelatedField and do this on my own. I don't like this method as I was hoping the filtering functionality would be something that you might consider pulling into the project seeing as you don't offer this already.


If you have time some evening I'd love to chat about the problem in more detail as well as talk about the current implementation I have for filtering to possibly get something baked into DRF by default.

@tomchristie
Copy link
Member

Sounds interesting.
Would need to understand the use-case better to comment on this.
How complete is your filtering system at the moment? (I guess I'm more interested in any docs/design rather than the implementation.)

As a rule I'd probably prefer to see things like filtering backends implemented and maintained as third-party repos, that are linked to from the main docs. That doesn't mean that I wouldn't be interested in contributing and helping get things documented and released to PyPI, but it does mean that I really want to keep the maintenance effort on the core framework sustainable, and farm out responsibility for neat useful plugins to the authors of those plugins themselves.

@pkkid
Copy link
Contributor Author

pkkid commented Dec 8, 2012

This makes sense. I'll spend another few days polishing things up and get some documentation and a repo so that you can better understand what I have and exactly the problem I hit. Will report back.

@pkkid
Copy link
Contributor Author

pkkid commented Dec 8, 2012

I pushed the code I currently have to the BitBucket repo here:
https://bitbucket.org/mjs7231/django-rest-framework-filtering

The basic idea is that it works exactly like Django's ORM filtering except you reference the serializer fields rather than the model fields. All filters are simply added as GET arguments to the current ListView urls. You can use it directly from the browsable API as well.

For example:
http://localhost:8000/api/v1/restaurant/?order_by=name&name__icontains=My

Example following a serializer field:
http://localhost:8000/api/v1/menu/?groups__name__icontains=new


A few thing I would love your input on:

  • Somehow be able to navigate RelatedFields and HyperlinkRelatedFields as mentioned above. You can see the Unsupported() call in views.py line 81 (because I have no idea how to get the correct serializer from only the view name).
  • I am not sure the best way to hook into your ListAPIViews. -- I am currently only subclassing generics.ListCreateAPIView and overriding the get_queryset() function. This leaves alot to be desired. I would love a more generic way to hook in allowing any ListView to pick this up. -- The mixin approach to the current generic.ListViews is making it a bit difficult to subclass these classes in way I am used to.
  • It's still very beta and not thoroughly tested at all.

@tomchristie
Copy link
Member

I am not sure the best way to hook into your ListAPIViews. -- I am currently only subclassing generics.ListCreateAPIView and overriding the get_queryset() function. This leaves alot to be desired. I would love a more generic way to hook in allowing any ListView to pick this up. -- The mixin approach to the current generic.ListViews is making it a bit difficult to subclass these classes in way I am used to.

The thing to do would be to implement this as a custom filter backend. That way it can be plugged into any list view, or set up to apply to all list views by default.

Somehow be able to navigate RelatedFields and HyperlinkRelatedFields as mentioned above.

I think I get the point, of being able to use the serializers to implicitly determine which fields are valid to filter against,
but I'm not too sure about a sensible approach to automagically navigating across relationships.
I'm also not exactly sure exactly what behaviour you're looking for.

@pkkid
Copy link
Contributor Author

pkkid commented Dec 10, 2012

The thing to do would be to implement this as a custom filter backend. That way it can be plugged into any list view, or set up to apply to all list views by default.

I tried this and hit a wall when trying to override the get_queryset() from ListView. It seems it can't be reliably done because you're trying to override a function from a sibling class (not a parent) class.

@tomchristie
Copy link
Member

@mjs7231 I'm confused - you shouldn't need to override get_queryset to implement a custom filter backend.
Perhaps you could show me what you tried?

Alternatively if you fancied slinging yourcode as it is at the moment onto github instead, I'd be happy to try to find some time to open a pull request against it.

@tomchristie
Copy link
Member

Closing. I don't want hyperlinked fields to be tightly coupled to serializers.

I guess I'd recommend either your initial option (3), or reconsidering if you want/need hyperlinked fields to be filterable by subfields on the related object. (eg. you might consider allowing nested serializations to be filtered by properties of the serializer, but hyperlinked serializations to be filtered only by their identity.)

@mjs7231 - I'd really like to include a link to your filter as a 3rd party backend. Having good 3rd party packages linked directly from the docs and described briefly would be great. If you're interested in that, maybe raise this on the discussion group and we can talk about how to implement what you currently have as an FilterBackend.

Thanks! :)

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

2 participants