Getting 404 error when serving files from media/ in template

Hello, I am having trouble diagnosing the root of a 404 error I’m getting when trying to serve files from my media folder in development mode. I have spent several hours trying to diagnose this by looking at similar issues on this and other forums, with no success. I apologize in advance if there is a simple fix I am overlooking!

I am developing an e-commerce site, and I have a model for products called Product and a model for images of those products called Image.

I am able to upload image files to the media folder using my product create view, but I can’t display them using my product detail template. I just get the default broken image icon from my browser.

The relevant code, as well as the errors I am seeing, is listed below.

Product model from models.py

class Product(models.Model):
    id = models.UUIDField(
        primary_key=True,
        default=uuid.uuid4,
    )

    vendor = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        null=True,
    )

    # Other fields such as price and sale status, etc, and Meta properties

Helper functions related to upload_to, and the Image model from models.py

# This function just helps to make a path to be used in the upload_to kwarg in my ImageField
def user_directory_path(instance, filename):
    now = datetime.datetime.now()
    year = now.year
    month = now.month
    day = now.day
    return 'vendor_{0}/{1}/{2}/{3}/{4}'.format(instance.product.vendor.id, year, month, day, filename)

# This function just adds 'images/' to the user_directory_path
def user_image_directory_path(instance, filename):
    return "images/" + user_directory_path(instance, filename)

class Image(models.Model):
    product = models.ForeignKey(
        Product,
        default=None,
        on_delete=models.CASCADE,
    )

    image = models.ImageField(
        upload_to=user_image_directory_path,
    )

ProductDetailView in views.py

class ProductDetailView(DetailView):
    model = Product

Relevant settings in settings.py

INSTALLED_APPS = [
   #...
    "PIL",
   #...
]

DEBUG = True

MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'

Relevant portion of product_detail.html template

{% if product.image_set.all %}
{% for image in product.image_set.all %}
<img src="{{ image.image.url }}" alt="{{ product }}"/>
{% endfor %}
{% endif %}

urls.py

urlpatterns = [
    #...
    path(
        "product/<uuid:pk>/",
        views.ProductDetailView.as_view(),
        name="product-detail",
    ),
    #...
]
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

404 Error message in terminal where running local server

Not Found: /media/images/vendor_1/2025/3/20/pencil-34532_1280.png
"GET /media/images/vendor_1/2025/3/20/pencil-34532_1280.png HTTP/1.1" 404 2644

i think MEDIA_URL = '/media/' is problem.
maybe your project set media url like 127.0.0.1//media/, but you request 127.0.0.1/media/

change MEDIA_URL = 'media/' and try it.

if settings DEBUG is False, it is other problem.

In addition to verifying your DEBUG setting, please confirm what directory the file pencil-34532_1280.png resides in.
(Identify the full directory path for it.)

It is not. Using /media/ is actually necessary under some specific circumstances.

The Note box in the docs for MEDIA_URL identifies the difference between the two. It shouldn’t be a problem here when using runserver.

Thank you for the replies @white-seolpyo and @KenWhitesell

I have DEBUG = True in settings.py.

The full path is django-ecommerce/media/images/vendor_1/2025/3/20/pencil-34532_1280.png, where django-ecommerce/ is the root folder for the project.

media url must be start with {MEDIA_URL}. why start with django-ecommerce??

Because @charlieterle has provided the path, as requested. It’s the URL that you’re thinking of.

And just to be clear - you have verified that there is a file named pencil-34532_1280.png in that directory?

That section of the urls.py file that you posted at Getting 404 error when serving files from media/ in template - is that your root urls.py file or your app urls.py file? (The media urls definition should be in your root urls file.)

The section of urls.py that I posted was indeed in my app directory, not my root directory. I moved the code into the root directory and now the files are being served. Thank you so much for the help!