Static file folder trouble

Hi. I hope you can help. I am trying to make my first real Django project demo for a collegue. She likes knitting and stuff. :slight_smile:

I got the site to work with generic views and model with ImageField. I also got the upload_to working. Everything is showing up on the site. The problem is I must have messed up alle the staticdirs, media_root and all that, because the images uploaded via admin end up in a weird folder and the console log says it looks for static/static/ folder. Can you help me spot where I have made something fundamentally wrong in the dir settings or the model’s upload_to?

Dont be confused by the two different fields on the model regarding the image. It is the ImageField I would like to work and not the image_url (which was my attempt at using external image link. Worked, but I would like to learn the static stuff better).

You can find all the code here (click ‘show code’): https://replit.com/@JesperQvist1/sider

The page is in danish but I think you will do fine. :wink:

Please ask, if I explained it badly.

Your media file directory and your static file directory should be two completely separate locations. The two shouldn’t be mixed.

Set up one directory for STATIC_ROOT and path for STATIC_URL, and a separate directory for MEDIA_ROOT and path for MEDIA_URL. Do not mix the two of them. The static files are for “system-provided” files only. The media files are for user-uploaded content.

Also, keep in mind that the upload_to attribute is relative to MEDIA_ROOT.

Thank you Ken.
I will try to make the changes you have suggested. Afterwards I will post here again.

Hi again. I changed the folder structure to what you said (I hope).

Deleted the old content. Made a new page and uploaded an image. It ended up in the right folder (again, I hope, from what you wrote).

How do I now reference it in my template file? I tried some different versions, but none worked.

(I left the field image_url empty, since I plan on deleting this and focus on the image_file instead)

Depends up what you’re looking to do with it in your template. It’s a field of a model, that has a number of attributes. See the docs at filefield and fieldfile.

I just wanted the image to show. I tried these 3 different, but with no luck:

<img src="/media/{{ post.image_file }}"><br>
<img src="{{ post.image_file.url }}"><br>
<img src="{% static post.image_file %}"><br>

Assuming post is a reference in the context to an instance of a model containing a FileField named image_file, that should work. Which of your views and templates are you trying this in?

I am sorry. I did not understand that. But this is the model (I deleted a CharField called image_url, because I dont need it anymore):

class Post(models.Model):
    title = models.CharField(max_length=100)
    text = models.TextField()
    image_file = models.ImageField(null=True, blank=True, upload_to='images')

and the view:


class BlogDetailView(DetailView): # new
  model = Post
  template_name = "post_detail.html"

And what’s being rendered in the html for <img src="{{ post.image_file.url }}"><br>?

If you open up the Django shell and run commands like:
Post.objects.get(id=1).title
Post.objects.get(id=1).image_file
Post.objects.get(id=1).image_file.url

what is the output?
(Assuming you have an entry in Post with an id = 1)

The html code on the page shows
<img src="/media/images/djangoimage.png" alt="" width="500" height="600">
I can’t run Django shell (AFAIK) on replit. (I am on a semi-locked work-pc)

Ok, so the html is being rendered properly. If you’re getting a 404 on that URL, then the issue is either with your MEDIA_ROOT or web server configuration - but Django is working correctly at this point.

Thank you Ken. I will try to test it on an other computer tomorrow. Maybe that will do the trick. :slight_smile:

Another thing I noticed - you’ve got MEDIA_ROOT as being within your project directory. You really don’t want to do that in a production environment. You want MEDIA_ROOT to be something accessible to the web server, but not part of your project-deployment tree. (In general, the same is true for STATIC_ROOT as well. These directories contain files that should be served directly by your web server and not by your application.)

I tested some more now. Maybe these info help shed some light.
In my template I tried a heap of different ways to get the image showing. Some of these as an example:

<img src="media/{{ post.image_file }}" alt="" width="200" height="200"><br>
<img src="media{{ post.image_file }}" alt="" width="200" height="200"><br>
<img src="{{ post.image_file.url }}" alt="" width="200" height="200"><br>
<img src="{{ post.image_file }}" alt="" width="200" height="200"><br>
<img src="{{ post.image_file.path}}" alt="" width="200" height="200"><br>

Results in this in the console:

"GET /post/1/ HTTP/1.1" 200 1247
"GET /static/css/base.css HTTP/1.1" 304 0
Not Found: /media/images/logo_ide.jpg
Not Found: /post/1/Logo
Not Found: /mediaimages/logo_ide.jpg
"GET /media/images/logo_ide.jpg HTTP/1.1" 404 2497Not Found: /post/1/mediaimages/logo_ide.jpg
Not Found: /post/1/media/images/logo_ide.jpg
"GET /post/1/Logo HTTP/1.1" 404 2455
"GET /mediaimages/logo_ide.jpg HTTP/1.1" 404 2494
"GET /post/1/mediaimages/logo_ide.jpg HTTP/1.1" 404 2515
"GET /post/1/media/images/logo_ide.jpg HTTP/1.1" 404 2518

Hope it helps

My folder structure is like this. Could you show me the right way?
ROOT FOLDER
├───core
├───media
│ └───images
├───pages
│ ├───migrations
├───static
│ └───css
├───templates
└───venvdjangodemo

Got it running now. It results in:

>>> from pages.models import Post
>>> Post.objects.get(id=1).title
'Logo'
>>> Post.objects.get(id=1).image_file
<ImageFieldFile: images/logo_ide.jpg>
>>> Post.objects.get(id=1).image_file.url
'/media/images/logo_ide.jpg'

What’s your deployment environment? How are you running Django in production?

Neither the directory for MEDIA_ROOT nor the directory for STATIC_ROOT should be anywhere within the directory structure for your project.

Precisely how you configure that in a production environment is dependant upon that environment.

Deployment can be a knarly issue - you’ll want to spend some time reading How to deploy Django | Django documentation | Django and the links on that page that are important to your specific environment.

I plan on using Heroku with the Heroku CLI (via Github), but I only develop locally right now to learn.
Did you see the other answers I gave above to your other questions? (sorry if I managed to split the thread)

Yea - it all jives with my responses here - Static file folder trouble - #7 by KenWhitesell and here - Static file folder trouble - #11 by KenWhitesell

Nor does anything you’ve posted alter my response before this one.

Unfortunately, I don’t use Heroku and don’t really know anything about it - hopefully someone with more knowledge will chime in.

I googled some more and the problem still exists. Do you think this could help, if I put it in my urls.py?:

if settings.DEBUG:
    # Serve media files in development server.
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)