Mohit Harshan
Mohit Harshan

Reputation: 1986

Check if all objects belong to a list django

Template:

{% for level in levels %}
    {% if level.todo_set.all in tasks %}
    <li>
        <a href="javascript:;"><img src="{{ level.badge.url }}" alt="" /></a>
    </li>
    {% else %}
    <li>
        <a href="javascript:;"><img src="{{ level.locked_badge.url }}" alt="" /></a>
    </li>
    {% endif %}
{% endfor %}

views.py:

@login_required(login_url="/account/login/")
def StudentPublicProfile(request, pk=None):
    student = User.objects.get(pk=pk)

    levels = Level.objects.all()

    todos = ToDo.objects.all()
    list = []

    tasks = Task.objects.filter(student=student)
    for task in tasks:
        list.append(task.todo)

    context = {"student": student, "levels": levels, "tasks": list, "todos": todos}

    return render(request, "student_public_profile2.html", context)

models.py:

class Level(models.Model):
    number = models.IntegerField()
    badge = models.ImageField()
    locked_badge = models.ImageField()
    timestamp = models.DateTimeField(
        auto_now_add=True, auto_now=False, blank=True, null=True
    )
    unlock = models.CharField(max_length=10, default="A")

    def __str__(self):
        return str(self.number)

    def get_absolute_url(self):
        return reverse("student:level-detail", kwargs={"pk": self.pk})


class ToDo(models.Model):
    level = models.ForeignKey(Level, on_delete=models.CASCADE)
    name = models.CharField(max_length=150)
    description = models.TextField()
    timestamp = models.DateTimeField(
        auto_now_add=True, auto_now=False, blank=True, null=True
    )

    def __str__(self):
        return self.name


class Task(models.Model):
    level = models.ForeignKey(Level, on_delete=models.CASCADE)
    todo = models.ForeignKey(ToDo, on_delete=models.CASCADE)
    student = models.ForeignKey(User, on_delete=models.CASCADE)
    title = models.CharField(max_length=150)
    content = models.TextField()
    timestamp = models.TimeField(auto_now=True)
    datestamp = models.DateField(auto_now=True)
    like = models.ManyToManyField(User, related_name="user_likes", blank=True)
    is_verified = models.BooleanField(default=False, blank=True)

    def __str__(self):
        return self.title

Basically, each level contains multiple todos. I want to check if all todos of the level are contained in the tasks list. This is what I'm doing in the template. But I'm not getting a correct result. What could be the issue here? Here I'm checking if all todos of a level are completed by a particular user. Only when a todo is completed it gets saved in Task

Upvotes: 0

Views: 843

Answers (2)

Mohit Harshan
Mohit Harshan

Reputation: 1986

levellist = []
for level in levels:
    if (
        ToDo.objects.filter(level=level).count()
        == Task.objects.filter(student=student, level=level).count()
    ):
        levellist.append(level.number)
    perc = (len(levellist) / len(levels)) * 100

In Template:

{% for level in levels %}
    {% if level.number in levellist %}
    <li>
        <a href="javascript:;"><img src="{{ level.badge.url }}" 
        alt=""/></a>
    </li>
    {% else %}
    <li>
        <a href="javascript:;"><img src="{{ level.locked_badge.url }}" 
        alt=""/></a>
    </li>
    {% endif %}
{% endfor %}

Found a fix!

Upvotes: 0

Carl Brubaker
Carl Brubaker

Reputation: 1655

You are probably best to handle this inside your view.

for level in levels_list:
    if Todo.objects.filter(level=level).count() == Task.objects.filter(student=student, level=level).count():
        return (level completion code)

Upvotes: 1

Related Questions