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