Django compare two users of a model and if one is the current user return the other user

Question:

I have this really simple friendship model that just consists of two users. After all if user1 is friends with user2 then user2 is friends with user1 automatically. I would like to filter all the results by the current user and if a row contains the current user I would like to return the other user.

So basically I want to return all records if the current user is either userone or usertwo and if the current user is usertwo swap the values so the current user is userone.

Currently it works but only one way using the following model, serializer and view

Model:

class Friendship(models.Model):
    userone = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name="friendone"
    )
    usertwo = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name="friendtwo"
    )

    created_at = models.DateTimeField(auto_now_add=True, verbose_name="created at")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="updated at")

    class Meta:
        unique_together = ["userone", "usertwo"]

    def __str__(self):
        return "{} is friends with {}".format(self.userone, self.usertwo)

    def save(self, *args, **kwargs):
        if self.userone == self.usertwo:
            return "Same person friendship should happen mentally"
        else:
            super().save(*args, **kwargs)

serializer:

class FriendSerializer(serializers.ModelSerializer):
    profile2 = serializers.SerializerMethodField()

    class Meta:
        model = Friendship
        fields = [
            "usertwo",
            "profile2"
        ]

    def get_profile2(self, obj):
        profile2_obj = Profile.objects.get(id=obj.usertwo.profile.id)
        profile2 = ProfileSerializer(profile2_obj)
        return profile2.data    

and view:

class FriendList(generics.ListAPIView):

    permission_classes = [permissions.IsAuthenticated]

    serializer_class = FriendSerializer
    name = "friends_list"

    def get_queryset(self):
        user = self.kwargs["user"]
        
        return Friendship.objects.all().filter(userone=user)

The way it’s set up is userone will always be the logged in user.

I have searched but cannot find information on how to handle this situation so guidance is appreciated.

Asked By: crawlingdev

||

Answers:

You can modify the get_queryset method in the view to filter by the current user and swap the values if the current user is usertwo:

def get_queryset(self):
    user = self.request.user
    queryset = Friendship.objects.all().filter(Q(userone=user) | Q(usertwo=user))
    for friendship in queryset:
        if friendship.usertwo == user:
            friendship.userone, friendship.usertwo = friendship.usertwo, friendship.userone
    return queryset
Answered By: Wariored
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.