Query M2M from Django template language

This might be a rookie problem but I cannot find a way around it.

I am trying to implement add recipe to favourites.

The view and model work properly as when I hit the button once it sends the request and adds the recipe to the user's favourites. Then when clicked again it removes it correctly from the database.

Alas now when i try to make visible on the template I ran into trouble with the template language.

I cannot find a way to check if the current user's profile has liked the paginated recipe.

I have the following class based list view

class Home(ListView):
    model = Recipe
    template_name = 'home.html'
    cloudinary_name = settings.CLOUDINARY_STORAGE.get('CLOUD_NAME')
    extra_context = {
        'cloudinary_name': cloudinary_name,
    }
    paginate_by = 2

    def get_queryset(self):
        return Recipe.objects.order_by('id').prefetch_related('profile__recipecomment_set__recipe')

and the following Recipe model

class Recipe(models.Model):
    title = models.CharField(
        max_length=TITLE_MAX_LENGTH,
        validators=(
            MaxLengthValidator(TITLE_MAX_LENGTH),
            MinLengthValidator(TITLE_MIN_LENGTH),
        ),
        null=False,
        blank=False,
    )

    profile = models.ForeignKey(
        Profile,
        on_delete=models.RESTRICT,
        null=False,
        blank=True,
        editable=False,
    )

    favourites = models.ManyToManyField(
        Profile,
        related_name='favourite',
        default=None,
        blank=True,
    )

the template.html is as follows, this is the code that doesn't work

{% for recipe in page_obj %}
    {% if request.user.profile.id in recipe.favorites %}
        <button>Recipe added to favourites</button>
    {% else %}
        <button>Add to favourites</button>
    {% endif %}
{% endfor %}

the pagination works, everything else is working except that I cannot check if the user has added each recipe to his favourites or not.

At last I found an answer myself. It might not be the best but it works.

In the Home view I added a static method that checks each item in the context object_list and adds an attribute that later can be used inside the template.

    @staticmethod
def is_in_favourites(request, recipe):
    if request.user.is_authenticated:
        return True if recipe.favourites.filter(id=request.user.profile.id).exists() else False
    return False

def get_context_data(self, *, object_list=None, **kwargs):
    ctx = super().get_context_data(object_list=object_list, **kwargs)
    for i in ctx.get('object_list'):
        i.is_in_favourites = self.is_in_favourites(self.request, i)
    return ctx
Back to Top