sixovov947
sixovov947

Reputation: 215

How to reverse check if object exisit in many to many django?

I have two models:

Model Student:
     name = models.CharField()
     ..... ....
     wishlist = models.ManyToManyField(University, blank=True)

Model University:
      name = models.CharField()
      ...... . .. . . . .

Basically am just creating a wishlist by which user can like on a university and then add it to their wishlist ! ( am expressing this via a heart icon ), So when user reclicks on same item then it will remove it from the wishlist, thats it !

The problem is that, how to check if a user has liked particular university ?

here is my code:

def index(request):
    univesity = University.objects.filter(is_approved=True)
    context = {'univesity': univesity}
    return render(request, 'search/index.html', context)

above is where i fetch all university for searching purpose ! In this i need to check if the use have already added the university to the wishlist relationship. And if its true then the heart icon will turn into red else empty color !

And now this is how i show on template

{% if data.student_set.all %}
     <button><em class="icon ni ni-heart-fill" ></em></button>
{% else %}
     <button><em class="icon ni ni-heart"></em></button>
{% endif %}

It doesnt work the way i expected ! please guide

Upvotes: 2

Views: 211

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477170

You can check if that person liked a university by annotating the Universities with an Exists subquery [Django-doc]:

from django.contrib.auth.decorators import login_required
from django.db.models import Exists, OuterRef

@login_required
def index(request):
    universities = University.objects.annotate(
        liked=Exists(Student.wishlist.through.objects.filter(
            student=request.user, university_id=OuterRef('pk')
        ))
    ).filter(is_approved=True)
    context = {'universities': universities}
    return render(request, 'search/index.html', context)

If Student is the user model. If that is not the case, you first should fetch the logged in user, and use that in the .filter(student=…, …) part.

Then we can render this in the template with:

{% for university in universities %}
    {{ university }}
    {% if university.liked %}
        <button><em class="icon ni ni-heart-fill" ></em></button>
    {% else %}
         <button><em class="icon ni ni-heart"></em></button>
    {% endif %}
{% endfor %}

Note: You can limit views to a view to authenticated users with the @login_required decorator [Django-doc].

Upvotes: 1

Related Questions