if "tasks" not in request.session:
request.session['tasks'] = []
return render(request, "tasks/index.html", {
# "tasks": tasks
"tasks": request.session['tasks']
})
def add(request):
if request.method == “POST”:
task = request.POST.get(‘task’)
form = NewTaskForm(request.POST)
if form.is_valid():
task = form.cleaned_data[“task”]
request.session['tasks'] += [task]
# or we can try doing it this way
# request.session['tasks'] += task
return HttpResponseRedirect(reverse("tasks:index"))
else:
return render(request, "tasks/add.html",{
"form": form
})
return render(request, "tasks/add.html",{
"form": NewTaskForm()
})
and then in index.html we have:
{% extends ‘tasks/layout.html’ %}
{% block body %}
<h1>Tasks</h1>
<ul>
{% for task in tasks %}
<li>{{task}}</li>
{% empty %}
<li>No tasks</li>
{% endfor %}
</ul>
<a href="{% url 'tasks:add' %}">Add a new task</a>
{% endblock %}
HERE’S THE PROBLEM:
if we use request.session[‘tasks’] += [task] where task = ‘abc’
we get in the html abc
but if we use:
if we use request.session[‘tasks’] += ‘abc’
we get in the html :
a
b
c
Okay cool. The session library is working as it should, but there seems to be a misunderstanding on strings in python. A string in python is iterable, so using for value in "some string" will have an iteration for each character in that string. This is why you are seeing 'a', 'b', 'c' being displayed individually.
If request.session["tasks"] is a list, then you can concatenate another list to it via request.session["tasks"] += [val1, val2] or you can directly append a single value via request.session["tasks"].append(value).
In short continue using request.session["tasks"] += [task] or switch to:
I understand what you are saying but if I print(request.session[‘tasks’] after I set request.session[‘tasks’] += ‘abc’ I get [‘a’, ‘b’, ‘c’] if I use request.session[‘tasks’] = ‘abc’ I get abc
if request.session[‘tasks’] is a list why when adding request.session[‘tasks’] += [task] do I not have a list of lists? What I end up with is a list of strings (which is what I want).
UPDATE, ahh I think I got it. In python when you add a list to a list you just extend the list. the other ways will add each iterable element
I’m not explaining myself well. When request.session['tasks'] += 'abc' gets executed, the string abc is considered a list, so it will combine the lists. For example:
x = [1, 2, 3]
x += [4, 5]
assert x == [1, 2, 3, 4, 5]
This is because an iterator on a string in python will go over each individual value. For example:
for value in 'abc':
print(value)
> "a"
> "b"
> "c"
Thus when you do request.session["tasks"] += 'abc' you’re combining the existing list request.session["tasks"] and the list of ["a", "b", "c"] (this is a simplification of strings). So if you want to use the += operator with a list, you need to use a list of strings or use .append rather than the += operator.