0

I'm trying to create a django app in which one user can add other user as Friend. Here's what I did,

models.py,

class Friend(models.Model):
    users = models.ManyToManyField(User)
    current_user = models.ForeignKey(User, related_name='all', null=True)

views.py

# view for adding or removing friends
def change_friends(request, pk):
    new_friend = User.objects.get(pk=pk)
    data = Friend.objects.get(current_user=request.user)
    frnds = data.users.all()
    new_friend in frnds:
        data.users.remove(new_friend)
    else:
        data.users.add(new_friend)
    redirect(request.META['HTTP_REFERER'])


# Displaying frinends,
def following(request, id=None):
    my_friend, created = Friend.objects.get_or_create(current_user_id=id)
    all_friends = my_friend.users.all()
    return render(request, 'all/follow.html', {'all_friends': all_friends})

This code was working fine until I added friends from 1 account only, but when I added several friends from several accounts it started showing an error get() returned more than one Friend -- it returned 2!.

How can we fix that? Thank You!

  • 1
    Possible duplicate of [django - get() returned more than one topic](https://stackoverflow.com/questions/22063748/django-get-returned-more-than-one-topic) – sandes Apr 25 '18 at 04:22

2 Answers2

0

Delete all Friend instances in admin and change model to:

   class Friend(models.Model):
       users = models.ManyToManyField(User)
       current_user = models.OneToOne(User, related_name='friend', on_delete=models.CASCADE, null=True)

then views should be:

# view for adding or removing friends
def change_friends(request, pk):
    new_friend = User.objects.get(pk=pk)
    friends = request.user.friend.users.all()
    new_friend in friends:
        request.user.users.remove(new_friend)
    else:
        request.user.users.add(new_friend)
    redirect(request.META['HTTP_REFERER'])


# Displaying frinends,
def following(request, id=None):
    my_friend, created = Friend.objects.get_or_create(current_user_id=id)
    all_friends = my_friend.users.all()
    return render(request, 'all/follow.html', {'all_friends': all_friends})

If you use many_to_many to record friends relationship,it should be better set model as:

current(OneToOne) users(ManyToMany)

If you use ForeignKey to record friends relationship,it should be better set model as:

current(ForeignKey) user(ForeignKey)

Update If you can't change models anymore,just change code to:

def change_friends(request, pk):
    new_friend = User.objects.get(pk=pk)
    data = Friend.objects.filter(current_user=request.user)
    has_user = False
    for x in data:
        if new_friend in x.users.all():
            has_user = True
            x.users.remove(new_friend)
    if not has_user:
        firend = Friend.objects.filter(current_user=request.user).first()
        if friend:
            friend.users.add(new_friend)
        else:
            friend = Friend.objects.create(current_user=request.user)
            friend.users.add(new_friend)
    redirect(request.META['HTTP_REFERER'])
Ykh
  • 7,567
  • 1
  • 22
  • 31
0

in change friend function this line of code change like this

 new_friend = User.objects.filter(pk=pk).first()

Try this...

Shihabudheen K M
  • 1,347
  • 1
  • 13
  • 19