Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use one to many models in Django rest framework

I got two simple models, first one is

class Post(models.Model):
    user = models.ForeignKey("common.MyUser", related_name="post_user")
    act = models.ForeignKey("activities.Act", related_name="post_act")
    post_title = models.CharField(max_length=30, blank=True)
    post_content = models.CharField(max_length=140)
    post_thumb_url = models.URLField()
    post_create_time = models.DateTimeField(auto_now=True)

and the second one is

class Comment(models.Model):
    post = models.ForeignKey("post.Post", related_name="comment_post")
    user = models.ForeignKey("common.MyUser", related_name="comment_user")
    reply_id = models.IntegerField()
    comment_content = models.CharField(max_length=140)
    comment_create_time = models.DateTimeField(auto_now=True)

Each post may have some comments.and now I wanna get each post info as well as all its comments using post id.For example:

api.example.com/post/?post_id=1 (This post has two comments) and return

 {
        "id": 26,
        "user": 22,
        "post_comment": [{
            "reply_id": 12,
            "comment_content": "How are you doing",
            "comment_create_time": "2015-11-19",
        },
        {
             "reply_id": 32,
            "comment_content": "My name is Sun",
            "comment_create_time": "2015-11-19",
        }]
        "post_title": " ",
        "post_content": "Thank you,bro.",
        "post_thumb_url": "http://www.example.com",
        "post_create_time": "2013-12-31"
}

In Django rest framework I using this

class PostSerializer(serializers.ModelSerializer):
"""Post api fields"""
post_comment = CommentSerializer(source="comment_post") //this may be the key

class Meta:
    model = Post
    fields = ("id", "user","post_comment", "post_title", "post_content", "post_thumb_url", "post_create_time") 

class CommentSerializer(serializers.ModelSerializer):
    """Comment api fields"""

class Meta:
    model = Comment
    fields = ("id", "reply_id","comment_content", "comment_create_time", "post", "user")

Any way to make this work? Thanks.

EDIT: Here is my view

class PostList(generics.ListCreateAPIView):
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,IsOwnerOrReadOnly)
    queryset = Post.objects.all()
    serializer_class = CommentSerializer

    def perform_create(self, serializer):
        serializer.save(user=self.request.user)

    def get_queryset(self):
        queryset = Post.objects.all()
        post_id = self.request.query_params.get('post_id', None)
        if post_id is not None:
            queryset = queryset.filter(id=post_id)
        return queryset
like image 506
Windsooon Avatar asked Jan 10 '16 16:01

Windsooon


1 Answers

You should set the many=True parameter.

# ##################
# ##### MODELS #####
# ##################

class Post(models.Model):
    user = models.ForeignKey("common.MyUser", related_name="post_user")
    act = models.ForeignKey("activities.Act", related_name="post_act")
    post_title = models.CharField(max_length=30, blank=True)
    post_content = models.CharField(max_length=140)
    post_thumb_url = models.URLField()
    post_create_time = models.DateTimeField(auto_now=True)

class Comment(models.Model):
    post = models.ForeignKey("post.Post", related_name="comment_post")
    user = models.ForeignKey("common.MyUser", related_name="comment_user")
    reply_id = models.IntegerField()
    comment_content = models.CharField(max_length=140)
    comment_create_time = models.DateTimeField(auto_now=True)


# #######################
# ##### SERIALIZERS #####
# #######################

class CommentSerializer(serializers.ModelSerializer):
  class Meta:
    model = Comment
    fields = ("id", "reply_id","comment_content", "comment_create_time", "post", "user")

class PostSerializer(serializers.ModelSerializer):
    # This line is what changed:
    # post_comment = CommentSerializer(source="comment_post")
    post_comment = CommentSerializer(many=True)

    class Meta:
        model = Post
        fields = ("id", "user","post_comment", "post_title", "post_content", "post_thumb_url", "post_create_time")
like image 132
Daniel Williams Avatar answered Nov 10 '22 19:11

Daniel Williams