views:

110

answers:

2

Hi, I am having difficulties with listing this type of data. Scenario is as follows:

  1. user1 add's a friend called user2
  2. user2 confirms that user1 is his friend

what should happen is user2 and user1 see's each others name in their friends list. What's happening now is I am able to add user2 to user1 friends list but user1 cannot see user2 in his/her list. My question is how do I get user1 to show up in user2's list and user2 to show up in user1's friend list if a user has confirmed friendship? I was thinking of utilizing the confirmation status in the model and because that user1 and user2's id is both in the confirmed relationship I don't see any integrity issues here. Any tips?

Friendship model:

class Friendship(models.Model):
        NOT_CONFIRMED = 1
        PENDING= 2
        CONFIRMED = 3

        STATUS_CHOICES = (
                (NOT_CONFIRMED, 'Not Confirmed'),
                (PENDING, 'Pending'),
                (CONFIRMED, 'Confirmed'),
        )
        from_friend = models.ForeignKey(User, related_name='friend_set')
        to_friend = models.ForeignKey(User, related_name='to_friend_set')
        confirmed = models.IntegerField(choices=STATUS_CHOICES,
default=NOT_CONFIRMED)

        class Meta:
                unique_together = (('to_friend', 'from_friend'),)

        def __unicode__(self):
                return '%s, %s' % (self.from_friend.username,
self.to_friend.username)

Views to render the friendships (as you can see, I have been playing with the filtering):

@login_required
def friends_list(request, username):
        user = get_object_or_404(User, username=username)
        #friends = [friendship for friendship in user.friend_set.filter(Q
(confirmed=2) | Q(confirmed=3))]
        friends = Friendship.objects.filter(
                Q(to_friend=user) | Q(confirmed=3)
        )

        # get friends latest 10 shows
        friend_shows = Show.objects.filter(user__in=friends).order_by('-id')
        return render_to_response('habit/friends_list.html', {
                'user': request.user,
                'friends': friends,
                'shows': friend_shows[:10],
                'username': username,
        })
+1  A: 

It's not obvious that your friendship model is associative. Is my friends list the list of all friendships in which I am the from_user? Or is it all friendships in which I am either the from_user or the to_user?

If it's the former, then every friend relationship is represented by two friendship objects, one indicating that you're my friend, and one indicating that I'm your friend. Whenever a user makes a request, you'll be adding two friendships. The status will indicate whether the person making the request is the from_user or the to_user. And when a request is confirmed or rejected, you'll update both friendships to reflect this.

If it's the latter, then every friend relationship is represented by a single friendship object. In this case, your object design will need to record which friend in the relationship made the request, so that when you examine the object you can tell which user can turn the request into a confirmed friendship.

Robert Rossney
A: 

Based upon this page: http://docs.djangoproject.com/en/dev/topics/db/queries/

The following code:

friends = Friendship.objects.filter(
        Q(to_friend=user) | Q(confirmed=3)
)

equates to: to_friend = user OR confirmed = 3. Which probably isn't what you want, based on your description.

This looks closer to what you want:

friends = Friendship.objects.filter(
        Q(to_friend=user) | Q(from_friend=user)
      , Q(confirmed=3)
)
Adam Luchjenbroers