Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Using ?include with HyperlinkedRelatedField #1154

Answered by sliverc
Nekidev asked this question in Q&A
Discussion options

I want to use HyperlinkedRelatedField for my serializer relationships since there are lots of relationships in my many-to-many rel and my server resources are limited, but allow users to use ?included=rel if they need it. Currently, if I use ?include= with a HyperlinkedRelatedField, I get:

Traceback (most recent call last):
 File "...\api\.venv\lib\site-packages\asgiref\sync.py", line 534, in thread_handler 
 raise exc_info[1]
 File "...\api\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
 response = await get_response(request)
 File "...\api\.venv\lib\site-packages\django\core\handlers\base.py", line 284, in _get_response_async
 response = await sync_to_async(
 File "...\api\.venv\lib\site-packages\asgiref\sync.py", line 479, in __call__
 ret: _R = await loop.run_in_executor(
 File "...\api\.venv\lib\site-packages\asgiref\current_thread_executor.py", line 40, in run
 result = self.fn(*self.args, **self.kwargs)
 File "...\api\.venv\lib\site-packages\asgiref\sync.py", line 538, in thread_handler 
 return func(*args, **kwargs)
 File "...\api\.venv\lib\site-packages\django\template\response.py", line 114, in render
 self.content = self.rendered_content
 File "...\api\.venv\lib\site-packages\rest_framework\response.py", line 70, in rendered_content
 ret = renderer.render(self.data, accepted_media_type, context)
 File "...\api\.venv\lib\site-packages\rest_framework_json_api\renderers.py", line 568, in render
 self.extract_included(
 File "...\api\.venv\lib\site-packages\rest_framework_json_api\renderers.py", line 338, in extract_included
 relation_queryset = list(relation_instance)
TypeError: 'NoneType' object is not iterable

I suppose this is because the field is not intended to load the data and therefore raises an error when the data to include is None. Is there any way to make the field have this behavior?

You must be logged in to vote

If you use hyperlinked related fields, if you have a resource in the included array, you do not know where it would be linked to. Therefore, as I see it, it is against the spec to allow this. See here where it talks about full-linkage which needs to be clear by the compound document. Anyhow, I am not so sure about the use case anyway.

My suggestion is to either have all relationships as hyperlinks or use included serializers, but not both together.

Replies: 2 comments 1 reply

Comment options

If you use hyperlinked related fields, if you have a resource in the included array, you do not know where it would be linked to. Therefore, as I see it, it is against the spec to allow this. See here where it talks about full-linkage which needs to be clear by the compound document. Anyhow, I am not so sure about the use case anyway.

My suggestion is to either have all relationships as hyperlinks or use included serializers, but not both together.

You must be logged in to vote
0 replies
Answer selected by Nekidev
Comment options

This is what I meant:

// No ?included=images
{
 "data": {
 ...,
 "relationships": {
 "images": {
 "links": {
 "self": "URL",
 "related": "URL",
 }
 }
 }
 }
}
// With ?included=images
{
 "data": {
 ...,
 "relationships": {
 "images": {
 "meta": {
 "count": 1
 },
 "data": [
 { "type": "image", "id": "500c5ecf-8d83-4333-8f0f-207941aaa552" }
 ],
 "links": {
 "self": "URL",
 "related": "URL",
 }
 }
 }
 },
 "included": [
 {
 "type": "image",
 "id": "500c5ecf-8d83-4333-8f0f-207941aaa552",
 "attributes": {
 ...
 },
 ...
 }
 ]
}

This way, the user can select what to load and prevent from sending a big body with things the user won't use. In my app I have big relationships (1k resources in many-to-many) and responses take too much time to get delivered.

You must be logged in to vote
1 reply
Comment options

OK I see. You can do this somehow with a custom ResourceRelatedField and custom JSONRenderer. However, I do not think that is the intended use case for compound documents, that when using include query parameter the JSON:API structure suddenly changes.

If you have issues with too large bodies, I rather recommend you use sparse field sets as per spec where you can define what fields you need returned. This is supported by DJA out of the box as long as you use rest_framework_json_api.serializers.ModelSerializer for your serializers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet
2 participants

AltStyle によって変換されたページ (->オリジナル) /