techedifice
techedifice

Reputation: 163

Want to join Three models and get API output

I have Three models. User which is Django default and Blogs and UserActive. I want to get an APi Output Like this:

[
    {
        "blog_id": 1,
        "user": {
            "id": 1,
            "username": "superuser",
            "email": "[email protected]",
            "first_name": "",
            "is_staff": true
            "last_active": "2021-04-12T13:36:47.367153Z"
        },
        "title": "first blog",
        "description": "hola",
        "image": "/images/phone.jpg",
        "create_at": "2021-04-08T14:24:51.122272Z",
        "update_at": "2021-04-08T14:37:00.287746Z"
    }
]

But I am only getting this output on api using get_blogs(request): from views.py Where last_active from UserActive model is not included I want to include it:

[
    {
        "blog_id": 1,
        "user": {
            "id": 1,
            "username": "superuser",
            "email": "[email protected]",
            "first_name": "",
            "is_staff": true
        },
        "title": "first blog",
        "description": "hola",
        "image": "/images/phone.jpg",
        "create_at": "2021-04-08T14:24:51.122272Z",
        "update_at": "2021-04-08T14:37:00.287746Z"
    }
]

Here is my models.py

class UserActive(models.Model):
    user_active_id = models.AutoField(primary_key=True, editable=False, null=False)
    user = models.OneToOneField(User, on_delete=models.CASCADE,null=False)
    last_active = models.DateTimeField(auto_now_add=True, editable=False)


class Blog(models.Model):
    blog_id = models.AutoField(primary_key=True, editable=False)
    title = models.CharField(max_length=128,null=False,blank=False)
    description = models.TextField(null=True,blank=True)
    image=models.ImageField(null=True,blank=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    create_at = models.DateTimeField(auto_now_add=True, editable=False)
    update_at =  models.DateTimeField(auto_now=True,editable=False)

Here is views.py:

@api_view(['GET'])
def get_users(request):
    user = User.objects.all().select_related('useractive')
    serializer = UserSerializer(user, many=True)
    return Response(serializer.data)


@api_view(['GET'])
def get_blogs(request):
    blogs = Blog.objects.all()
    serializer = BlogSerializers(blogs, many=True)
    return Response(serializer.data)

here is serializers.py

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id',  'username', 'email', 'first_name', 'is_staff', ]



class UserActiveSerializer(serializers.ModelSerializer):
    user = UserSerializer()
    class Meta:
        model = UserActive
        fields = '__all__'

class BlogSerializers(serializers.ModelSerializer):
    user = UserSerializer()
    class Meta:
        model = Blog
        fields = '__all__'

Upvotes: 0

Views: 49

Answers (2)

Neeraj
Neeraj

Reputation: 997

You need to have a reverse relationship from User to UserActive to get that field in UserSerializer.

Model:

class UserActive(models.Model):
    user_active_id = models.AutoField(primary_key=True, editable=False, null=False)
    user = models.OneToOneField(User, on_delete=models.CASCADE,null=False, related_name='user_active')
    last_active = models.DateTimeField(auto_now_add=True, editable=False)

Serializer:

class UserSerializer(serializers.ModelSerializer):
    last_active = serializers.DateTimeField(source='user_active.last_active', read_only=True)
    class Meta:
        model = User
        fields = ['id',  'username', 'email', 'first_name', 'is_staff', 'last_active']

Upvotes: 2

techedifice
techedifice

Reputation: 163

littel bit of modification is needed in UserSerializer. should use serializers.DateTimeField() instead of serializers.DateField() Model:

class UserActive(models.Model):
    user_active_id = models.AutoField(primary_key=True, editable=False, null=False)
    user = models.OneToOneField(User, on_delete=models.CASCADE,null=False, related_name='user_active')
    last_active = models.DateTimeField(auto_now_add=True, editable=False)

Serializer:

class UserSerializer(serializers.ModelSerializer):
    last_active = serializers.DateTimeField(source='user_active.last_active', read_only=True)
    class Meta:
        model = User
        fields = ['id',  'username', 'email', 'first_name', 'is_staff', 'last_active']

Upvotes: 0

Related Questions