How to get the name of the user with their id in follower and following system in Django rest framework?

Viewed 155

I want to create a follower and following system, and I created but I want to add username along with their following_user_id or user_id. How can I do this?

models.py

from django.db import models
from django.contrib.auth.models import User
from django.http import JsonResponse

## Create your models here.


class UserFollowing(models.Model):
    user_id = models.ForeignKey(User, related_name="following", on_delete=models.CASCADE)
    following_user_id = models.ForeignKey(User, related_name="followers", on_delete=models.CASCADE)
    created = models.DateTimeField(auto_now_add=True, db_index=True)

    class Meta:
        unique_together = (('user_id', 'following_user_id'),)
        index_together = (('user_id', 'following_user_id'),)
        ordering = ["-created"]

    def __str__(self):
        f"{self.user_id} follows {self.following_user_id}"

serializers.py/UserSerializers


class UserSerializer(serializers.ModelSerializer):

    following = serializers.SerializerMethodField()
    followers = serializers.SerializerMethodField()

    # for validate user email
    def validate_email(self, value):
        lower_email = value.lower()
        if User.objects.filter(email=lower_email).exists():
            raise serializers.ValidationError("Email already exists")
        return lower_email

    class Meta:
        model = User
        fields = ['id', 'first_name', 'username', 'last_name', 'email', 'password', 'date_joined','following','followers']
        # extra_kwargs for validation on some fields.
        extra_kwargs = {'password': {'write_only': True, 'required': True},
                        'first_name': {'required': True}, 'last_name': {'required': True},
                        'email': {'required': True}
                        }

    def get_following(self, obj):
        return FollowingSerializer(obj.following.all(), many=True).data

    def get_followers(self, obj):
        return FollowersSerializer(obj.followers.all(), many=True).data


    def create(self, validated_data):
        user = User.objects.create_user(**validated_data)  # create user
        Token.objects.create(user=user)  # create token for particular user
        return user

FollowingSerializer and FollowerSerializes

class FollowingSerializer(serializers.ModelSerializer):

    class Meta:
        model = UserFollowing
        fields = ("id", "following_user_id", "created")


class FollowersSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserFollowing
        fields = ("id", "user_id", "created")

ViewSets

class UserFollowingViewSet(viewsets.ModelViewSet):

    serializer_class = FollowingSerializer
    queryset = UserFollowing.objects.all()

class UserFollowerViewSet(viewsets.ModelViewSet):

    serializer_class = FollowersSerializer
    queryset = UserFollowing.objects.all()

Output

    {
        "id": 11,
        "first_name": "",
        "username": "John",
        "last_name": "",
        "email": "",
        "date_joined": "2021-04-30T08:43:48.577328Z",
        "following": [
            {
                "id": 19,
                "following_user_id": 14,
                "created": "2021-04-30T17:42:31.491779Z"
            }
        ],
        "followers": [
            {
                "id": 24,
                "user_id": 13,
                "created": "2021-04-30T17:48:56.153387Z"
            },
            {
                "id": 20,
                "user_id": 14,
                "created": "2021-04-30T17:46:38.001047Z"
            }
        ]
    },

I'm getting the following and followers list in the output, but in this list, I also want to add a username with their following_user_id or user_id.

Can anyone know about this?

2 Answers

You can create a username field inside the userfollowing model which lookes like this


class UserFollowing(models.Model):
    user_id = models.ForeignKey(User, related_name="following", on_delete=models.CASCADE)
    following_user_id = models.ForeignKey(User, related_name="followers",on_delete=models.CASCADE)
    created = models.DateTimeField(auto_now_add=True, db_index=True)
    username = models.Charfield(max_length=200, null=True)

and use signals to store the username in the username field, so you will get the username column after serializing

"following": [
            {
                "id": 19,
                "following_user_id": 14,
                "created": "2021-04-30T17:42:31.491779Z",
                "username":"maria"
            }
        ],
        "followers": [
            {
                "id": 24,
                "user_id": 13,
                "created": "2021-04-30T17:48:56.153387Z",
                "username":"angel"
            },

If I got you right, how about

class UserFollowing(models.Model):
    ...

    def __str__(self):
        f"{self.user_id.username} follows {self.following_user_id.username}"
 
    def getfolowers(self): # Get my followers object
        # return a query set of who is following me
        return UserFollowing.objects.filter(following_user_id=self.id)
Related