简体   繁体   中英

How to filter out Friends of user in search users function Django

I'm trying to filter out the friends of a user and also the current logged in user from a "search_users" function, I've tried using exclude() but keep getting an error I'm not sure whats wrong. I also wanted to add a "add friend" button next to the users, which I think I've done correctly on 'search_users.html. Error

views.py

@login_required
def search_users(request):
    query = request.GET.get('q')
    object_list = User.objects.filter(username__icontains=query).exclude(friends=request.user.profile.friends.all())
    context ={ 
        'users': object_list
    }
    return render(request, "users/search_users.html", context)

search_users.html

{% extends "feed/layout.html" %} {% load static %}
{% block searchform %}
<form
  class="form-inline my-2 my-lg-0 ml-5"
  action="{% url 'search_users' %}"
  method="get"
>
  <input name="q" type="text" placeholder="Search users.." />
  <button class="btn btn-success my-2 my-sm-0 ml-10" type="submit">
    Search
  </button>
</form>
{% endblock searchform %} {% block content %}
<div class="container">
  <div class="row">
    <div class="col-md-8">
      {% if not users %}
      <br /><br />
      <h2><i>No such users found!</i></h2>
      {% else %}
      <div class="card card-signin my-5">
        <div class="card-body">
          {% for user_p in users %}
          
          <a href="{{ user_p.profile.get_absolute_url }}"
            ><img
              src="{{ user_p.profile.image.url }}"
              class="rounded mr-2"
              width="40"
              height="40"
              alt=""
          /></a>  
          <a class="text-dark" href="{{ user_p.profile.get_absolute_url }}"
            ><b>{{ user_p }}</b></a
            >  
            
            <small class="float-right">
              <a
                class="btn btn-primary mr-2"
                href="/users/friend-request/send/{{ user_p.username }}"
                >Add Friend</a>
              </small>
          
          <br/><br />

          {% endfor %}
        </div>
      </div>
      {% endif %}
    </div>

    <div class="col-md-4">
      <div class="card card-signin my-5">
        <a href="{{ request.user.profile.get_absolute_url }}"
          ><img
            class="card-img-top"
            src="{{ request.user.profile.image.url }}"
            alt=""
        /></a>
        <div class="card-body">
          <h5 class="card-title text-center">{{ request.user }}</h5>
          <h6 class="text-center">
            {{ request.user.profile.friends.count }}
            <p class="text-muted">Friends</p>
          </h6>
          <p class="card-text text-center">{{ request.user.profile.bio }}</p>
        </div>
      </div>
    </div>
  </div>
  {% endblock content %}
</div>

models.py

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    image = models.ImageField(default='default.png', upload_to='profile_pics')
    slug = AutoSlugField(populate_from='user')
    bio = models.CharField(max_length=255, blank=True)
    friends = models.ManyToManyField('Profile', blank=True)

It should be

User.profile.objects.filter(username__icontains=query).exclude(friends=request.user.profile.friends.all())

You were getting an error earlier because you referred to the user object earlier and not the profile itself. User.profile gives the one to one related model profile instead.

You can read more about one to one relationships here. https://docs.djangoproject.com/en/3.1/topics/db/examples/one_to_one/

I would have done like this:

object_list = User.objects\
    .filter(username__icontains=query)\
    .exclude(profile__friends__in=request.user.profile.friends.all())\
    .exclude(id=request.user.id)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM