skip to Main Content

I want to use {% set … } but it has problem is django.template.exceptions.TemplateSyntaxError: Invalid block tag on line 126: ‘set’, expected ‘empty’ or ‘endfor’. Did you forget to register or load this tag?

what should i do ?

html file

<div class="carousel-inner">
   {% for knowledge in knowledges %}
       {% set count = 0 %}
       {% for photo in photo01s %}
           {% if photo.category01 == knowledge %}
           {% set count = count + 1 %}
                <div class="carousel-item {% if forloop.first %}active{% endif %}">
                    <div class="row">
                        <div class="card" style="background-image: url('{{ photo.image01.url }}');"></div>
                    </div>
                </div>
            {% endif %}
        {% endfor %}
     {% endfor %}
</div>                

models.py

class Knowledge(models.Model):
    name01 = models.CharField(max_length=100, null=False, blank=False)

    def __str__(self):
        return self.name01

class Photo01(models.Model):
    category01 = models.ForeignKey(Knowledge, on_delete=models.SET_NULL, null=True, blank=True)
    image01 = models.ImageField(null=False, blank=False)
    description01 = models.TextField()
    title01 = models.CharField(max_length=100, default='')

    def __str__(self):
        return self.title01

views.py

def knowledge01(request):
    knowledges = Knowledge.objects.all()
    photo01s = Photo01.objects.all()

    context = {'knowledges': knowledges, 'photo01s': photo01s}
    return render(request, 'photos/knowledge01.html', context)

I have tried several ways but it does not work.

2

Answers


  1. Don’t perform "join"s in the template. Templates should implement rendering logic, not business logic, and templates are notoriously slow, and thus it would not work very efficiently.

    Secondly, your template does not use count anyware, so setting this variable makes not much sense either. I assume the template has been generated by a chatbot, since chatbots often perform variable assignments in a template, and to make matters worse, "make up" template tags that do not exist.

    We can prefetch the images in the view:

    def knowledge01(request):
        knowledges = Knowledge.objects.prefetch_related('photo01_set')
    
        context = {'knowledges': knowledges}
        return render(request, 'photos/knowledge01.html', context)
    <div class="carousel-inner">
       {% for knowledge in knowledges %}
           {% for photo in knowledge.photo01_set.all %}
               <div class="carousel-item {% if forloop.first %}active{% endif %}">
                        <div class="row">
                            <div class="card" style="background-image: url('{{ photo.image01.url }}');"></div>
                        </div>
                    </div>
            {% endfor %}
         {% endfor %}
    </div>

    Note: Specifying null=False [Django-doc] is not necessary: fields are by default not NULLable.


    Note: Specifying blank=False [Django-doc] is not necessary: fields are by default not blank and thus are required by a form.

    Login or Signup to reply.
  2. You can use the with template tag.

    <div class="carousel-inner">
       {% for knowledge in knowledges %}
           {% with count = 0 %}
           {% for photo in photo01s %}
               {% if photo.category01 == knowledge %}
               {% with count = count + 1 %}
                    <div class="carousel-item {% if forloop.first %}active{% endif %}">
                        <div class="row">
                            <div class="card" style="background-image: url('{{ photo.image01.url }}');"></div>
                        </div>
                    </div>
                {% endif %}
            {% endfor %}
         {% endfor %}
    </div>   
    

    you haven’t used this count variable though

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search