template tag "with" list variable

I’m looking to use the django template tag like this:

{% with items=['item1', 'item2', 'item3'] %}
<ul>
    {% for item in items %}
        <li>{{ item }}</li>
    {% endfor %}
</ul>
{% endwith %}

But Django can’t seem to parse this. Is there a reason why this is not allowed? Or is there an alternative syntax?

Yes, the Django template language is not designed nor intended as a complete programming language. The expectation is that data elements will be defined in the views and passed to the template through the context.

Not within the Django template language. Jinja might be able to do this (I don’t know, I don’t use it.)

Or, you may want to explore a more “holistic” approach where you take another look at what you’re trying to do overall, and perhaps reconsider your approach.

Hi Ken, thanks for the quick reply.

I’m trying to build flexible and reusable form components like this (using bootstrap5 classes):
test_component.html:

{% for item in items %}
<div class="form-check form-check-inline">
    <input class="form-check-input" type="checkbox" id="{{item}}" value="{{item}}" name="{{field_name}}">
    <label class="form-check-label" for="{{item}}">{{item}}</label>
</div>
{% endfor %}

Which I can then use with:

{% include 'test_component.html' with items=['item1', 'item2', 'item3'] field_name='field1' %}

If we create a view, then we’d need to pass in the list of items as a variable to the view, which seems more complicated than it needs to be.

I’ve found a workaround by passing in a string like items='item1 item2 item3' and in the test_component.html, you’d do {% for item in items.split %} instead.

But, any suggestions or alternatives would be greatly appreciated.

I guess in general, I would be taking a different approach. From where I sit, that just looks like a form field widget being rendered, and so the fundamentals for this would be the template being rendered for a form field using a custom widget.

In the general case, I would assume the items to be rendered would be available in the view.

Hi Ken, let’s assume the items to be rendered is not available in the view, I’m not sure to be honest. For example, if the form is for a json field and could change quite often depending on the situation. In this case then, would it still make sense to make many different views with a different items list?

You wrote:

They exist already as form and widget classes. Adding bootstrap5 into the mix is an issue of changing attributes of the rendered elements.

What Django provides as templates - while extremely useful - are not expected to be everything that everyone is ever going to need. They’re a starting point, but not an ending point.

See Crispy forms for another take on this. (Not that I’m specifically recommending this for you in this case, but simply as an example of another “Django-ish” way of defining and rendering forms.)

Why would you need to make “many different views”? I guess I’m just not seeing your use-case for needing to do this this way.

<opinion>
My reaction from this is that you’re trying to make Django work like some other framework. You have an identified problem to solve, and because you’ve done “ABC” on “Framework X” to solve that problem, you’re looking to implement “ABC” in Django - where the “native Django” method of a solution may lead you in a different direction.

Or, possibly, that you’re not sufficiently aware of everything that Django can do to see the options available for this.

In either case, I freely acknowledge that I may be very wrong here, and corrections and clarifications are welcome.
</opinion>

You wrote:

Something somewhere needs to know what those items are - otherwise, how can you render it?

This implies that this question is as much a hypothetical as a real issue to be solved. In the context of the above, my first guess is that you may have views that aren’t being created as they should to fit the predominate Django patterns.

I always try to live by my philosophy of “Don’t fight the framework.” If there’s a disconnect between how I’m thinking about how to solve a problem and the primary paradigm provided by a framework, then it’s my way of thinking that needs to change, not the framework.

In this case then, the answer becomes one of taking a step back and looking at the complete situation in context.

It may be that you’re looking at your views as being too narrowly focused.

Note: I should clarify that my use of the term “view” here is not to be construed as addressing only the view function. It encompasses the entire body of code that ends up being executed between the time the request is received and the time the response is returned. This would then include model code being executed by queries, any utility / third-party modules that may need to be invoked, form classes being instantiated and processed, and templates being rendered.