I am working on a Django project whereby I want to check if a user is subscribed to a product or not. I have created in my models.py several model instances and I am stuck on how to check if the user is subscribed inside the template. Here is my template where I loop through the fetched data:
<ul>
{% for content in content %}
{% if content.model.is_premium and user.is_subscribed %}
<li>Premium</li>
{% else %}
<li>Not premium</li>
{% endif %}
{% endfor %}
</ul>
Here is my views.py :
@login_required(login_url='/user/login')
def homepage(request):
content = ModelContent.objects.all()
categorys = Category.objects.all()
models = MyModels.objects.all()
suggestions = MyModels.objects.all()[:3]
# profiles = Profile.objects.filter(user__is_creator=True)
context = {"categorys": categorys, "models": models, "content":content, "suggestions":suggestions}
return render(request, 'users/home.html', context)
And here is the models.py:
User = get_user_model()
class MyModels(models.Model):
owner = models.ForeignKey(Profile, on_delete=models.CASCADE, null=False, blank=False)
name = models.CharField(max_length=500, null=False, blank=False)
username = models.CharField(max_length=500, null=False, blank=False, unique=True)
title = models.CharField(max_length=500, null=False, blank=False)
description = models.TextField(max_length=500, null=False, blank=False)
image = models.ImageField(upload_to='img', blank=True, null=True)
placeholder = models.ImageField(upload_to='img', blank=True, null=True)
sex = models.CharField(max_length=50, choices=SEX_CHOICES, default=NONE)
category = models.ForeignKey(Category, on_delete=models.CASCADE, null=False, blank=False)
content_id = models.UUIDField(default=uuid.uuid4, primary_key=True, unique=True, editable=False)
created = models.DateField(auto_now_add=True)
is_popular = models.BooleanField(default=False)
is_premium = models.BooleanField(default=False)
# posted_content = models.ManyToManyField('ModelContent', related_name='model_content')
def __str__(self):
return self.username
class ModelContent(models.Model):
model = models.ForeignKey(MyModels, on_delete=models.CASCADE, null=False, blank=False )
title = models.CharField(max_length=500, null=False, blank=False)
date = models.DateTimeField(auto_now_add=True)
content_id = models.UUIDField(default=uuid.uuid4, primary_key=True, unique=True, editable=False)
class Meta:
ordering = ['-date']
def __str__(self):
return str(self.title)
class Subscription(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='subscriptions_to_product')
model = models.ForeignKey(MyModels, on_delete=models.CASCADE, related_name='subscriptions_from_subscriber')
is_subscribed = models.BooleanField(default=False)
def __str__(self):
return f"{self.user.username} subscribed to {self.model.username}"
The views.py is inside an app called 'users' while the models.py is inside an app called 'posts'. I have tried doing this :
{% for content in content %}
{% if content.model.is_premium %}
{% with subscription=request.user.subscriptions_to_product.filter(model_id=content.model_id).first %}
{% if subscription and subscription.is_subscribed %}
<li>User Subscribed</li>
{% else %}
<li>User Not Subscribed</li>
{% endif %}
{% endwith %}
{% else %}
<li>Not premium</li>
{% endif %}
{% endfor %}
But it did not work.
This is not the task of the template. Templates should be used only for rendering. Not for business logic. You can use an Exists
subquery [Django-doc]:
from django.db.models import F
from django.db.models.functions import Exists
@login_required(login_url='/user/login')
def homepage(request):
content = ModelContent.objects.annotate(
is_subscriped=Exists(
Subscription.objects.filter(
model__modelcontent=OuterRef('pk'),
user=request.user,
is_subscribed=True,
)
)
)
categorys = Category.objects.all()
suggestions = MyModels.objects.all()[:3]
context = {
'categorys': categorys,
'content': content,
'suggestions': suggestions,
}
return render(request, 'users/home.html', context)
In the template, you then render this as:
{% for content in content %}
{% if content.model.is_premium %}
{% if content.is_subscribed %}
<li>User Subscribed</li>
{% else %}
<li>User Not Subscribed</li>
{% endif %}
{% else %}
<li>Not premium</li>
{% endif %}
{% endfor %}