Why am I getting a Server Error (500) when Creating Variables in a Template from W3Schools Django Syntax Section ?

I am stumped on why I am getting the following Server Error (500) shown below and need some help.

I have been working through W3Schools Django, everything was going well, I got the 2 examples at the top of the page ( Template Variables and Create Variable in View) working, but when I got to Django Template Variables and did the Create Variables in Template example I had this Server Error (500) problem.

I have pushed my work up to GitHub

In my template.html file

I have this code.

<!DOCTYPE html>
<html>
<body>

{% with firstname = "Tobias" %}
<h1>Hello {{ firstname }}, how are you ?</h1>
{% endwith %}

</body>
</html>

and in my views.py file, as I can’t put a link to it, it is under same members folder as before.

I have this code

from django.http import HttpResponse
from django.template import loader

def testing(request):
   template = loader.get_template('template.html')
return HttpResponse(template.render())

I just want to get an understanding on why I am getting this 500 error, when it looks like I have the correct code. If anyone knows why this is happening, I would appreciate some feedback thanks.

There should be no spaces around firstname = "Tobias", this should be like firstname="Tobias"

@RobertWSON - Side note: Whenever you get an error message in your browser, it’s more useful to copy/paste the error message with the complete traceback from the console where you’re running runserver, than to post an image of the browser window.

In template.html, I changed
{% with firstname = "Tobias" %} to
{% with firstname="Tobias"%}

and it worked in the localhost with no errors, thanks!

What I would like to know though, is why does it not like a space with {% with firstname="Tobias" %} , but it does not mind a space with <h1>Hello {{ firstname }}, how are you ?</h1> ?

Also with views.py

def testing(request):
     template = loader.get_template('template.html')
     return HttpResponse(template.render())

Why does return HttpResponse(template.render()) not need request ?

Hi Ken

I got it working by changing {% with firstname = "Tobias" %} to {% with firstname="Tobias"%}

From your last reply, I think what you mean is, showing the console with localhost is the best way to go and if there is an error it can be seen there, is that what you mean ?

What I would like to know though, is why does it not like a space with {% with firstname="Tobias" %} , but it does not mind a space with <h1>Hello {{ firstname }}, how are you ?</h1> ?

Also with views.py

def testing(request):
     template = loader.get_template('template.html')
     return HttpResponse(template.render())

Why does return HttpResponse(template.render()) not need request ?

Not quite. There’s a terminal console in which you run manage.py runserver that shows the output from the server. It’s that output that I’m talking about. It’s going to look something like this:

System check identified no issues (0 silenced).
June 28, 2023 - 07:42:24
Django version 4.0.6, using settings 'dt.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
INFO "GET /btup/2/ HTTP/1.1" 200 11342
ERROR "GET /btup/1/ HTTP/1.1" 500 84170

First, note that this still permits spaces before and after the expression - exactly like {{ firstname }} does. In that regards, there is no difference between the two.

But, there are multiple places within the template facility where spaces within an expression are not allowed, such as with filters. The expression {{ firstname|title }} is valid, but {{ firstname | title }} is not.

That’s just a limitation of the Django template parser. The “why” is “because the rendering engine was written that way”.

Because it doesn’t need one. See the docs for it at Request and response objects | Django documentation | Django.

If you’re really looking to answer the questions of “why were these things written this way”, then your best bet is to dive through the mailing list archives, the trac tickets, the commit history, and old versions, to see what you can piece together from what information may exist. But in some cases the answer may simply turn out to be an arbitrary choice being made.

1 Like

Hi Ken

Thanks for the advice, I understand that it is better to read errors from running python manage.py runserver on command line or in terminal of VSCode for example.

I also can see that Django rendering engine is written in a way that it does not allow spaces with filters or firstname=“Tobias” , but allows space before and after an expression eg {{ firstname }}.
It is just the way Django language is setup with a template parser.

I am still not completely sure though, why HttpResponse(template.render()) does not need a request for

def testing(request):
     template = loader.get_template('template.html')
     return HttpResponse(template.render())

when you have def testing(request) to start with

I’m not following what you’re trying to ask here.

All views receive the request as a parameter - that’s defined by Django.

Whether or not the view uses that request is a separate issue.

Ken

I am just going to show 2 different examples from Django Template Variables, so it can be seen what I am trying to understand.

The Template Variables and Create Variable in View are both in the same example .

This is HTML for Template Variables

<!DOCTYPE html>
<html>
<body>

<h1>Hello {{ firstname }}, how are you?</h1>

<p>In views.py you can see how to create the variable.</p>
<p>In template.html you can see how to use the variable.</p>

</body>
</html> 

and Create Variable in View is views.py shown below

from django.http import HttpResponse
from django.template import loader

def testing(request):
  template = loader.get_template('template.html')
  context = {
    'firstname': 'Linus',
  }
  return HttpResponse(template.render(context, request))

So HttpResponse takes both request and context (which I believe is an object with its property and property name)

Now with Create Variables in Template example

This is HTML

<!DOCTYPE html>
<html>
<body>

{% with firstname="Tobias" %}
<h1>Hello {{ firstname }}, how are you?</h1>
{% endwith %}

</body>
</html>

and this is views.py

from django.http import HttpResponse
from django.template import loader

def testing(request):
  template = loader.get_template('template.html')
  return HttpResponse(template.render())

As you can see in this example return HttpResponse(template.render()) does not use request, whereas in the previous example it used both request as well as context that it needs to for the name.

This is what I am not clear on yet, why this example does not need to use request ?

Because there is nothing in the template being rendered that is using any data that would be supplied by either a context or the request.

Actually, from the portions posted here, the first example doesn’t need the request either.

(Side note: I think you’d be a lot better off learning Django from any of the Official Django Tutorial, the Django Girls Tutorial, or the MDN Django tutorial. A rather cursory review of that tutorial you’ve linked highlights a couple items that I think should be changed. You might want to check out GitHub - wsvincent/awesome-django: A curated list of awesome things related to Django for some other resources as well.)

Hi Ken

I have looked into your reply about request.
You mentioned Because there is nothing in the template being rendered that is using any data that would be supplied by either a context or the request.

I can see, looking at it from a request perspective

views.py

from django.http import HttpResponse
from django.template import loader

def testing(request):
  template = loader.get_template('template.html')
  return HttpResponse(template.render())

request is not needed with return HttpResponse(template.render())
because template = loader.get_template(‘template.html’) is acting like a request to get code that is needed from template.html file

Coding return HttpResponse(template.render(request)) gives a server error 500

But, return HttpResponse(template.render())
is using template.render(), which to me seems like it is a method to pick up (‘template.html’) a template file for using code to return a web page. This works and displays a web page using this.

From a context perspective

views.py

from django.http import HttpResponse
from django.template import loader

def testing(request):
  template = loader.get_template('template.html')
  context = {
    'firstname': 'Linus',
  }
  return HttpResponse(template.render(context, request))

With return HttpResponse(template.render(context, request))

context is definitely needed because we are getting the variable value from the same views,py file

request does not need to be used because like before template = loader.get_template(‘template.html’) is acting like a request to get code that is needed from template.html file.

If we do not need to use request then return HttpResponse(template.render(context)) can just be used and it would work.

It is interesting to note here though, that when a context is in a views.py file, when returning an HttpResponse , both
return HttpResponse(template.render(context, request))
or
return HttpResponse(template.render(context))

can be used, why is this ?

But from just a request perspective with no context it cannot work:

as only return HttpResponse(template.render()) works
but return HttpResponse(template.render(request)) does not work.

That’s a mischaracterization of what’s happening here.

The loader.get_template method returns a Template object.

That Template object has a render method that optionally accepts a request as a parameter.

However, if you look at the calling signature for render, you’ll see that the first parameter (if unnamed) is context (an object of type dict), not request (an object of type HttpRequest). You cannot pass an HttpRequest as a function parameter that is expecting a dict.

Therefore:

is an improper call. It would need to be template.render(request=request).

Being in the same file is not relevant. The only data relevant is what is in that specific view and the functions that it calls - which may be in that file or in different files.

Again, see the docs referenced above regarding the signature of the render method. template.render(request) is an invalid call.