Skip to content

Set custom "type" for ResourceRelatedField #193

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
EmilTemirov opened this issue Jan 22, 2016 · 4 comments
Closed

Set custom "type" for ResourceRelatedField #193

EmilTemirov opened this issue Jan 22, 2016 · 4 comments

Comments

@EmilTemirov
Copy link

Hi, all!
I have the following Django model:

class Comment(model.Model):
    text = models.TextField()
    parent_comment = models.ForeignKey('self', null=True, blank=True, on_delete=models.CASCADE)

I want to be able to obtain a list of comments with "parent" in relationships, for example:

{
  "data": [
    {
       "type": "comments",
        "id": "1",
        "attributes": {
          "text": "First comment"
        },
        "relationships": {
          "parent": {
            "data": null
          } 
        }
    },
    {
       "type": "comments",
        "id": "2",
        "attributes": {
          "text": "Child comment"
        },
        "relationships": {
          "parent": {
            "data": {
              "type": "comments",
              "id": 1
            }
          } 
        }
    },
  ]
}

My serializer:

class CommentSerializer(ModelSerializer):
    parent = ResourceRelatedField(source='parent_comment', read_only=True)

    class Meta:
        model = Comment
        fields = ('text', 'parent',)

In my ViewSet I have defined resource_name = 'comments', but it is doesn't work for "parent" in relationships. At the present time, "type" of "parent" is "Comment". How can I fix this issue?

@leifurhauks
Copy link

It should now possible to specify the resource name on the model class, thanks to #152 .

for example:

class Comment(models.Model):
    class JSONAPIMeta:
        resource_name = 'comments'
   # the rest of the model definition...

@jerel
Copy link
Member

jerel commented Jan 22, 2016

leifurhauks' example should solve this. I'll close and if it doesn't fix then let us know.

@jerel jerel closed this as completed Jan 22, 2016
@EmilTemirov
Copy link
Author

Thanks! Please, describe this feature in the documentation.
Actually, I have found in sources that there is possible to set model attribute in the ResourceRelatedField, for example:

class MySerializer(serializers.ModelSerializer):
    parent = relations.ResourceRelatedField(source='comment_parent', model=Comment, read_only=True)

But it does not work. It will work properly if override the following lines in renderers.py:

@staticmethod
def extract_relationships(fields, resource, resource_instance):
       # ....
       if isinstance(field, ResourceRelatedField):
                # special case for ResourceRelatedField
                if hasattr(field, 'model'):
                    res_data = resource.get(field_name)
                    relation_data = {
                        'data': OrderedDict([('type', relation_type), ('id', res_data['id'])]) if res_data else None
                    }
                else:
                    relation_data = {
                        'data': resource.get(field_name)
                    }
       # ....

I'm not sure that it is right approach, so will use leifurhauks' solution, but it very seems like a bug -)

@leifurhauks
Copy link

If I remember correctly, the ResourceRelatedField used to use the model kwarg to determine the type name when read-only, but I think this behaviour may have been changed since then to support heterogeneous to-many relationships (e.g. polymorphic relationships with objects of more than one type).

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