Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.

Debugging: Part 1

In this lesson, you’re going to see how to approach debugging, which is an important part of software development! In all_projects.html, you’re trying to display everything that you have available for one project that’s inside your database.

You’re missing an image. To add an image, you’re going to have to load the static files with a template tag at the beginning of your file:

{% load static %}

Comments & Discussion

reblark on Nov. 3, 2019

I simply do not understand this:

...{% static project.image%}...

How is it that the database is named “project” ? Where does that happen? And why is it “....image” instead of “....img”.

Plus my code <img src="{% static project.image %}" alt="screenshot of project"> does not return the alternate text, but does return the empty image icon.

Clearly, I am having trouble with debugging. Except, prior to this, I found four problems in my code and fixed them.

reblark on Nov. 3, 2019

Wow. I am really lost. You say we have “two times the same file name.” Really? I only see once instance of testproject.png. Further, I don’t understand how the code you just wrote refers to this particular file.

Plus, I can’t find my database files. We entered info in the Django shell, but I can’t find the database tables. In the project viewer in Pycharm, I see sqlite3, but in the database viewer on the right, I just see db and it has nothing in it.

reblark on Nov. 3, 2019

I have images in the proper place and I can view them when I hard code the image path as you show. It’s great, but I have some problem with the database, I think.

Martin Breuss RP Team on Nov. 3, 2019

Let’s look at two aspects of your questions here:

Viewing the Database Contents

Not sure why you can’t view the contents of your SQLite file in PyCharm’s Database explorer. You might need to set it up first, and you can follow these instructions to do so: www.jetbrains.com/pycharm/guide/tips/create-sqlite-connection/.

If for some reason this doesn’t work, or if someone doesn’t have the professional version of PyCharm, you can instead us the free DB Browser for SQLite.

Give it a go and see whether you can view the entries in your Database.

File Path vs. Project Instance Attribute

I think you might be mixing up two different things here:

  • File Path: This is the location of your image file in your project. Think about where it resides in your folder structure. The file path of the one file you used so far is in projects/img/testproject.png.
  • Project Instance Attribute: As defined in your models.py, you are using a Project object that has an attribute called image. In that image attribute you are defining the path to the image file (see above).

This means that project.image should refer to a path string, e.g. projects/img/testproject.png. It’s a variable pointing to a value.

Further, the project variable name comes from your for loop in all_projects.html. You say:

{% for project in projects %}
    <img src="{% static project.image %}" alt="screenshot of project">
{% endfor %}

project is the iterator, the identity of it changes and refers to each of the Project instances that you created, which again corresponds to the rows in your database.

project.image therefore refers to the image attribute of each Project instance, which in turn is a variable for the path to the image’s location in your project starting from the static folder down the file structure. There’s a lot going on here and it’s easily confusing. Try to revisit and understand what the different pieces are:

  1. The file path of an image file
  2. The Project instance with an image attribute
  3. The iterator that you called project (lowercase p!), which is a reference to every Project (capital P!) instance

Hope that helps to clarify it.

reblark on Nov. 4, 2019

Thank you for this detailed comment. Much of this stuff I do know but somewhere, I am missing something. So, I am going to do these two lessons (debugging) again. Couple of things I wonder. If I drop images into the image folder, is that a problem? In other words, do I have make a database entry for each image? Also, in the python shell. I thought [] is mutable. In other words, if I wanted to change the file name in the folder from 720720 to 720720.jpg, I would simply enter image[0] = ‘720720.jpg’ (it’s the first file in the folder), but that didn’t work.

Martin Breuss RP Team on Nov. 5, 2019

You are not editing files when you work with the Django shell. While it’s possible to change file names with Python, you aren’t doing anything like that in this tutorial.

Lists in Python are mutable, that’s correct. However, you are not changing the file name when you type the code you mentioned into the console:

image[0] = '720720.jpg' 

What the code above does is replace the first item of a list called image with the string '720720.jpg'.

There are a couple of assumptions you are making with this code snippet that don’t correspond to the project you’re working with, most importantly:

  • You are not editing files (nor file names)
  • Django ORM objects are not lists

Check out our Guide to Object-Oriented Programming to refresh what that means.

Martin Breuss RP Team on Nov. 5, 2019

It is perfectly fine to drop image files into the img folder–that is exactly what you are meant to do and where the image files on my computer come from. I took some screenshots and dropped them into the img folder.

What you are doing with the Django shell and what you are putting into the database is simply a string representation of the location of the image files, not the actual image files.

Does that make sense?

reblark on Nov. 6, 2019

Hi Martin, Thank you for these responses. I have sorted through them all and understand them for the most part. The part about these not being lists is something I want to address later but for now I hope to understand why my code below returns the standard html missing file icon but not the alt message:

{% load static %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test-11.6.19</title>
</head>
<body>
    <h1>Hello, again!</h1>
    {{ projects }}
    {% for project in projects %}
        <img src="{% static project.image %}" alt="There is a problem acquiring the image.">
        <h1>{{ project.title}}</h1>
        <p>{{ project.description }}</p>
        <p>{{ project.technology }}</p>
    {% endfor %}


</body>
</html>

reblark on Nov. 6, 2019

Something else I have noticed. The code to produce the image, whether it’s static or pulled from the database, is at the top of the html code. When I run my code with the “print” example, the image file name appears above the <h1> tab, which I believe is correct. However, the “file not found” icon appears at the bottom. Also, in your example run with the “print” code, both the alt entry and the image file name appear at the bottom of lines for test project. The questions here are why do both the file name and the “alt” entry appear and why are they at the bottom?

reblark on Nov. 8, 2019

In Debuggin 1 at 2:07, you say something about “two time template…” I cannot understand it. What did you say?

reblark on Nov. 8, 2019

I have looked at this so many time and I have asked you about it but did not get an answer. This line: <img src=”{% static project.image %}” alt=”There is a problem acquiring the image.”> Does not produce the text when I go to localhost:8000/orojects. The page does display the “file not found” icon from html. Your displays show the text. Why are they different?

reblark on Nov. 8, 2019

OK. I think I know this pretty well now. But. What is missing has to do with the database. The original entries that I made using the django shell, are still there. I have changed the entries in the image column many times using the PyCharm database inspector. I have gone over this video and redone my code so many times that I know there is not an answer to my question in the videos. If, in the Django shell, I enter something like projects[1].image, I get the original file name, as opposed to the current one. When I try to change it by entering projects[1].image = ‘whatever.png’ it doesn’t work. I get a TypeError: “QuerySet’ object does not support item assignment. You have told me that before but I tried it anyway because you haven’t told me how to change the database entries. Please tell me how to do that.

Martin Breuss RP Team on Nov. 9, 2019

Hei @reblark–you can change the database entries both from within PyCharm, as well as through the Django shell:

PyCharm Database Inspector

Just as you probably did, you can double-click on a cell and then edit it. Before the changes will be propagated to your database, you’ll have to click the Submit button on the top row of the menu of the Database Inspector.

Check out this resource that explains it more and shows an image of how the button looks like.

Django Shell

Here you are working with Python objects that you receive by doing database queries.

You can change the attributes on these items, and the image path is one attribute on a row object. However, to propagate the changes you’ll again need to commit and save them to the database–similar as you have to do it with a button click when using the PyCharm database inspector.

The error that you are getting seems to indicate that you might be working with a ~list (a QuerySet object) instead of a single row instance object.

To debug, you can assign the output of projects[1] to a variable and inspect that variable in more detail. Is it one object, or a collection of objects? Can you access the .image attribute correctly? What happens when you try to change it (it should work–even though it still won’t be in your database until you commit the changes!!). If you get an error, what suggestions come up when googling it? Etc.

I’d suggest you look into the learning path on object-oriented programming that I mentioned earlier, it’ll be helpful to get a good grasp on these concepts.

Martin Breuss RP Team on Nov. 9, 2019

At 2:07 I say:

two times template tags

and that’s about using Django’s template tags {% %} both for:

{% load static %}

and the <img> tag’s src attribute further down:

<img src="{% static project.image %}">

reblark on Nov. 10, 2019

I could try this: If you want to remove all the data from all your tables, you might want to try the command python manage.py flush. This will delete all of the data in your tables, but the tables themselves will still exist. Then try to re-enter the correct file names. What do you think?

reblark on Nov. 10, 2019

Oh, thanks for the response about two times template tags.

reblark on Nov. 10, 2019

Also, I still haven’t heard why my text of the alt tag doesn’t show up instead of the html file not found image.

Martin Breuss RP Team on Nov. 10, 2019

Sure, you could try flushing your DB and then putting back the information. You can even delete the SQLite file (=your DB) and Django will re-build the tables for you.

However, editing it as I mentioned above should work as well.

If you just want to see the images display, you can also change the file name of your image files to fit whatever is recorded in the DB at the moment. It’s just important that the path to the image file (including it’s name), and the path that is recorded in the DB match each other.

reblark on Nov. 11, 2019

Thanks. I did the flush and build a new database. The interesting part is that the db inspector lists the new items as 4,5,6 while 1,2,3 (the files I first entered are gone. I am sure that I will understand that someday. It seems that the db entries go to some mysterious place in the universe.

The more interesting question for me is the one that I have asked three times, “why my text of the alt tag doesn’t show up instead of the html file not found image.”

Perhaps I have missed the answer, but I certainly have not seen it.

reblark on Nov. 11, 2019

Also, I finally got the bit about small p projects just being an iterator. I would like to suggest using a different word for the iterator. As you know, it could anything, even “x”. But, while it’s good to use something relevant I think “project” is a confusing choice. I think using a word that simply stands out as an iterator is a better idea. Two cents.

Martin Breuss RP Team on Nov. 12, 2019

I hear you, but I personally wholeheartedly disagree. Using explicit and descriptive naming in your coding practice makes reading, understanding, and debugging code much easier, and more future-proof.

I’d suggest to always use descriptive naming for your iterators, rather than using x or i. Doing so makes reading Python for loops like reading an English sentence:

for (each) project in (all the) projects (that exist): (do something on each) project

In a Python for loop, you are actually iterating over the instances–in this case the individual Project objects. project is not just a throw-away iterator as it is in some other languages, it is the actual object picked out of the iterable.

Martin Breuss RP Team on Nov. 12, 2019

Regarding your alt text not showing up: I don’t know why it isn’t showing up. If you are using it as intended then it should be appearing if your image file cannot be found.

You might have a typo somewhere or who-knows-what ¯\(ツ)\/¯

My tip is to try to make an alt tag work as expected on a tiny example, e.g.: * build a minimal HTML page and link to an image using a hardcoded path * does the image show up? * change the path so it cannot find the image file * does the alt text show up instead?

Once you got that minimal example to work as expected and you understand what’s happening there, move forward to implementing it in your Django app. Follow the steps described above again, but now working in a Django app + template.

reblark on Nov. 14, 2019

I totally agree with using descriptive naming and being consistent with PEP 8. Effective descriptive naming may be in the eye of the beholder.

Re: the alt tag, my code perfectly matches yours with this different result. I am not going to worry about it for now.

Thanks for being so responsive.

mogwaimonkey on Dec. 31, 2019

Hello, i am unable to get the browser to show the images. Instead it shows the alt text.

The message from the server is this: “GET /static/testproject.png HTTP/1.1”

I assume the problem is it’s missing the projects/img part of the path i.e. it should read /static/projects/img/testproject.png

This is my class Project where i have entered ‘projects/img’:

class Project(models.Model): title = models.CharField(max_length=100) description = models.TextField() technology = models.CharField(max_length=20) image = models.FilePathField(path=’projects/img’)

This is the for loop code i used in all_projects.html:

**{% for project in projects %}

    <h1>{{ project.title }}</h1>
    <img src="{% static project.image %}" alt="image not available">
    <p> {{ project.image }} </p>
    <p> {{ project.description }}</p>
{% endfor %}**

The browser is showing this part of the code: <p> {{ project.image }} </p>

as this: testproject.png

Also when i look in the sql database the image column for Project is also showing this: testproject.png

I assume it should be showing this instead: projects/img/testproject.png

Any idea why it is not showing the full path or what is wrong?

mogwaimonkey on Jan. 1, 2020

Update: I have since created a new object/row in the sqllite project table. I explicitly put the image path as ‘projects/img/daily.png’ and this results in that image being shown in the browser.

So the issue is definitely as a result of the Project class function not appending ‘projects/img’ to the start of the image column values that we assign.

mogwaimonkey on Jan. 1, 2020

Oops, please ignore my previous comments. I realise this all explained in the very next part of the tutorial.

Martin Breuss RP Team on Jan. 4, 2020

@mogwaimonkey Yes, that’s a little bug 🐛 we’re running into here. Sounds like you did a great deep-dive and figured things out for yourself (best way to debug, so well done! 👏).

For anyone else who is initially confused why the images don’t show up, please go ahead and watch Debugging Part 2.

reblark on Feb. 26, 2020

When you are trying to solve the db access problem with the static images, you insert a print statement. But, when you run it, it only prints for two instances not three. Why?

Martin Breuss RP Team on March 1, 2020

That’s simply because there are only 2 objects in the database. If you look closely, also the web view shows only two items.

Dave Wilson on March 26, 2020

I just want to give props to Martin on this whole series and his replies to everyone’s questions. He’s a natural teacher!

Martin Breuss RP Team on March 26, 2020

@Dave Wilson 😊 Thanks so much! Glad the series is helpful for you!

adrianaariza on April 23, 2020

Hi Martin, when I add {% load static%} the html marks an error. It says unexpected tokens.

Martin Breuss RP Team on April 24, 2020

Hi @adrianaariza, is this a PyCharm error (something that PyCharm highlights for you) or is your webapp not working and displaying an error message when you try to run it?

If it’s the first, check out this question that I found when searching for this online. Does it solve your situation when you follow Pavel’s suggestion?

If it’s the second, please send some more info on what you are doing, where it’s breaking, and the relevant code and error message, and I can look some more. Hope that does it, though :)

rivet on May 26, 2020

Hello Martin. Thank you for the great course, I’m enjoying it and your careful explanations have helped my understanding. However, I’m using Django 3 which I think is newer than the version you’re using, and the documentation for FilePathField is different. It says:

A CharField whose choices are limited to the filenames in a certain directory on the filesystem.

… which sounds exactly what we need. I’m finding the Django documentation here really unhelpful. I know that’s not your fault, but could you describe in a bit more detail what FilePathField is supposed to be for, and why we can’t use it here? Kind thanks!

Martin Breuss RP Team on May 28, 2020

Hi @rivet and glad you’re enjoying the course :)

It is totally possible to use a FilePathField() for this example, as you can see in the supporting written tutorial. The part that might trip you up, however, is that this field requires the use of an absolute path:

FilePathField.path Required. The absolute filesystem path to a directory from which this FilePathField should get its choices. Example: “/home/images”.

There are, however, elegant ways to solve this by dynamically generating the path through a function when the app runs.

Tl;dr: FilePathField is a good choice for this situation. There are always multiple ways to solve a problem, and the main aim here was to show how you can follow an error and figure out a solution. Hope that makes sense :)

abaninarendra on July 2, 2020

When I add load static in all_projects.html

{% load static %}

I get unexpected tokens for line

<!DOCTYPE html>

Martin Breuss RP Team on July 2, 2020

Hi @abaninarendra are you using the PyCharm Community Edition? From what I understand, it doesn’t support the Django integration in their free version, which is why this highlight may show up. This is just some IDE-internal notification and shouldn’t impact the functionality of your project, however. Let me know if that’s not the case.

If you are using the Professional PyCharm version and this error is still showing up, you can read up on Activating the Django Integration. Hope this helps!

tomislavm021 on July 20, 2020

Why whould anyone use shell to upload images into app? I still dont understand how to show images :/

Martin Breuss RP Team on July 21, 2020

Hi @tomislavm021 - you’re not uploading the images to your app using the CLI, you are just adding the path to where your images are stored through the command line.

In terms of images, think of your app like a file system. The images live somewhere in a folder. In order to link to them from a different place, you need to tell your app where they are located. Their location is also called their “path”.

What you need to give to Django in order to correctly display the images that you have already put into your app’s ~file system earlier on, is this path of each file. That’s what you’re adding through the CLI, and it’s just some text, not the actual image.

Does this help to clarify things?

Become a Member to join the conversation.