djangopostgresqlresthttp-headers

Why the get request won't get data from connected models?


My GET request to list all the posts and comments and replies, doesn't get all the connected models.

models.py

from django.db import models
from django.contrib.auth import get_user_model
from django.conf import settings

User = get_user_model()


class Post(models.Model):
    id = models.AutoField(primary_key=True)
    text = models.TextField(max_length=165)
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    date = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f'{self.author}: {self.text}'


class Images(models.Model):
    id = models.AutoField(primary_key=True)
    image = models.ImageField(upload_to='images/')
    post_id = models.ForeignKey(Post, on_delete=models.CASCADE)


class Comment(models.Model):
    id = models.AutoField(primary_key=True)
    text = models.CharField(max_length=165)
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    date = models.DateTimeField(auto_now_add=True)

serializers.py

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id', 'username')

class CommentSerializer(serializers.ModelSerializer):
    author = UserSerializer(read_only=True)
    replies = ReplySerializer(many=True, read_only=True)

    class Meta:
        model = Comment
        fields = "__all__"


class ImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = Images
        fields = ('image',)


class PostSerializer(serializers.ModelSerializer):
    images = ImageSerializer(many=True, read_only=True)
    author = UserSerializer(read_only=True)
    comments = CommentSerializer(many=True, read_only=True)

    class Meta:
        model = Post
        fields = "__all__"

views.py


class PostsViewSet(ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

urls.py

router = DefaultRouter()
router.register('posts', PostsViewSet)

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(router.urls)),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

So I created superuser and added some posts and images via admin panel. And after all that, I'm getting the following:

@baseUrl = http://localhost:8000/

GET {{baseUrl}}/posts/
Content-Type: application/json
HTTP/1.1 200 OK
Date: Mon, 27 Jan 2025 18:17:52 GMT
Server: WSGIServer/0.2 CPython/3.12.7
Content-Type: application/json
Vary: Accept
Allow: GET, POST, HEAD, OPTIONS
X-Frame-Options: DENY
Content-Length: 311
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
Cross-Origin-Opener-Policy: same-origin

[
  {
    "id": 1,
    "author": {
      "id": 1,
      "username": "admin"
    },
    "text": "first post",
    "date": "2025-01-22T18:34:56.097351Z"
  },
  {
    "id": 2,
    "author": {
      "id": 1,
      "username": "admin"
    },
    "text": "Second post",
    "date": "2025-01-27T11:07:42.331467Z"
  },

instead of something like:

{
    "id": 1,
    "author": {
      "id": 1,
      "username": "admin"
    },
    "text": "first post",
    "image": "url/to/image"
    "date": "2025-01-22T18:34:56.097351Z"
    "comments": {
      "author": {
      "id": 1,
      "username": "admin"
      "text": "something"
    }
 }

How can I fix it? And an unrelated question, how to pass image url as POST? -_-


Solution

  • Because the model provides the comments as .comment_set, so:

    class PostSerializer(serializers.ModelSerializer):
        comments = CommentSerializer(many=True, read_only=True, source='comment_set')
        # …