donkeyboy72
donkeyboy72

Reputation: 1943

Django Comparing user's list

I have a like feature which allows students to like in other pictures.

  def LikePicture(request,picture_id):
      p = Picture.objects.get(pk=picture_id)
      new_like, created = Like.objects.get_or_create(user=request.user, picture_id=picture_id)
      return HttpResponseRedirect(reverse('world:Boat', kwargs={'animal_id': the_id }))

At the moment , I'm trying to implement a restriction toward the people who likes a particular picture. I want only the people who are friends with a particular users to like their's picture and the only way I can do this is by implementing a friend models.

2 Users can only be friends if both users add each other.

I'm planning to use this friendship models unless someone has a better friendship models that we can both use to implement the restriction.

  class Friendship(models.Model):
    from_friend = models.ForeignKey(User, related_name='friend_set')
    to_friend = models.ForeignKey(User, related_name='to_friend_set')
    def __unicode__(self):
      return u'%s, %s' % (
        self.from_friend.username,self.to_friend.username)
    class Meta:
      unique_together = (('to_friend', 'from_friend'), )

We can bulid a relationship with

  >>> user1 = User.objects.get(id=1)
  >>> user2 = User.objects.get(id=2)
  >>> friendship1 = Friendship(from_friend=user1, to_friend=user2)
  >>> friendship1.save()
  >>> user1.friend_set.all()
  [<Friendship: user1, user2>, <Friendship: user1, user3>]

but inorder to become friends . the other users has to add the other users.

  >>> friendship3 = Friendship(from_friend=user2, to_friend=user1)
  >>> friendship3.save()
  >>> user2.friend_set.all()
      [<Friendship: user2, user1>]

Now , The problem is how can we edit the like function so it would only allows friends to like a picture.

I have thought of a way but I couldn't find a way to implement it into my like function. My idea is because we can grab the User object who own the picture and the guy who's trying to like the picture . We can compare each other friendlist . We get the user object who own the picture and we get the user object whose trying to like the picture.We then compare if the user who's own the picture has the user who's trying to like his picture on his friendlist >>> user1.friend_set.all() and we do it in reverse . If the user owner's picture is inside the request.user friendlist .Allow Like!!! .

So it's like , if both users have each other in the same friendlist . Allow like!!!

It would be something similar to this function

  def Like(request,picture_id):
      user1 = User.objects.get(user=request.user) # The Guy who trying to like the picture
      p = Picture.objects.get(pk=picture_id)
      user2 = User.objects.get(picture=p) # The owner of the picture
      if user1 is in user2.friend_set.all() AND if user2 is in user1.friend_set.all():
           new_like, created = Like.objects.get_or_create(user=request.user, picture_id=picture_id)
      else:
           message ('You can only like if you are an friend ')
           return HttpResponseRedirect(reverse('world:Boat', kwargs={'animal_id': the_id }))

      return HttpResponseRedirect(reverse('world:Boat', kwargs={'animal_id': the_id }))

Or we can compare Users object

>>> [friendship.to_friend for friendship in 
user1.friend_set.all()]
[<User: user2>, <User: user3>]

Upvotes: 1

Views: 322

Answers (1)

Aamir Rind
Aamir Rind

Reputation: 39659

Little bit improvement required:

class FriendshipManager(models.Manager):
    def is_friends(self, user_a, user_b):
        if self.get_query_set().filter(
            user__id=user_a.id, friend__id=user_b.id, is_accepted=True).exists() or \
            self.get_query_set().filter(
                user__id=user_b.id, friend__id=user_a.id, is_accepted=True).exists():
            return True
        else:
            return False


class Friendship(models.Model):
    user = models.ForeignKey(User)
    friend = models.ForeignKey(User, related_name='friends')
    is_accepted = models.BooleanField(default=False)

    objects = FriendshipManager()

    def __unicode__(self):
        return u'%s, %s' % (
            self.user.username, self.friend.username)

    class Meta:
        unique_together = (('user', 'friend'), )


def Like(request, picture_id):
    user = request.user
    p = get_object_or_404(Picture, pk=picture_id)
    pic_owner = p.user # i hope you have user relationship with pic here
    if Friendship.objects.is_friends(user, pic_owner) \
        pic_owner.id == user.id:
        # if the pic owner and requested user are friends
        # or user is liking his own pic
        new_like, created = Like.objects.get_or_create(
            user=user, picture=p)
    else:
        message ('You can only like if you are friends')
        return HttpResponseRedirect(
            reverse('world:Boat', kwargs={'animal_id': the_id }))

    return HttpResponseRedirect(
        reverse('world:Boat', kwargs={'animal_id': the_id }))

Added is_accepted field to make sure other person approved the friend request. Added is_friendsmethod in manager which will be used to check if two users are friends. In view also checked if requested user and picture owner are same then it means user can like its own posted picture. This code is untested but I hope this will serve you well.

Upvotes: 1

Related Questions