I just couldn't connect Railway volume With my django-Project

Here in settings.py I've added


if os.environ.get("MOUNT_MEDIA"):
    MEDIA_ROOT = "/app/media"
    print("Using Railway mounted volume for MEDIA_ROOT")
else:
    MEDIA_ROOT = BASE_DIR / "media"
    print("Using local folder for MEDIA_ROOT")

MEDIA_URL = "/media/"

in urls.py



if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
else:
    # allow Django to serve media in production (NOT recommended, but works)
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

Model is

    image = models.ImageField(upload_to="products", default="product.jpg")
    description = models.TextField(blank=True, null=True)

Whatever I do. I can't get to view those images..!

Here is the edit product view where I am being able to view the photo


@login_required
def edit_product(request, pk):

    product = get_object_or_404(Product, pk=pk, user=request.user)
    

    if request.method == "GET":
        # print("GET request for product data")
        # Return product data as JSON for prefill
        return JsonResponse({
            "id": product.id,
            "name": product.name,
            "price": float(product.price),
            "discounted_price": float(product.discounted_price) if product.discounted_price else "",
            "stock_quantity": product.stock_quantity,
            "description": product.description,
            "status": product.status,
            "image": product.image.url if product.image and hasattr(product.image, "url") else ""
        })

    elif request.method == "POST":
        # Update product with submitted form data
        product.name = request.POST.get("name")
        product.price = request.POST.get("price")
        product.discounted_price = request.POST.get("discounted_price") or None
        product.stock_quantity = request.POST.get("stock_quantity")
        product.description = request.POST.get("description")
        product.status = request.POST.get("status") == "True"

        if "image" in request.FILES:
            product.image = request.FILES["image"]

        product.save()

        return JsonResponse({"success": True, "message": "Product updated successfully!"})

    return JsonResponse({"error": "Invalid request"}, status=400)

and This is the JS to load the view.

// Fetch data to prefill
      fetch("{% url 'back:edit_product' 0 %}".replace("0", currentEditId))
        .then((res) => res.json())
        .then((data) => {
          document.getElementById("edit_name").value = data.name;
          document.getElementById("edit_price").value = data.price;
          document.getElementById("edit_discount_price").value = data.discounted_price;
          document.getElementById("edit_stock").value = data.stock_quantity;
          document.getElementById("edit_description").value = data.description;
          document.getElementById("edit_status").value = data.status ? "True" : "False";

          preview.innerHTML = "";
          if (data.image) {
            const img = document.createElement("img");
            img.src = data.image;
            preview.appendChild(img);
          }
        });

Even After Doing All this I can't just connect with my Volume with railway.
While using ssh I saw doing ls The uploaded product is uploaded to media/product/product.jpg file. But when I access website.com/media/product.image it says:

Not Found

The requested resource was not found on this server.

is the URL of this media is not working for that product?
Or not serving it?
What is it?

Root cause

There is nothing wrong with your model, view, or JavaScript.

The issue is that Django cannot reliably serve uploaded media files in production on Railway.

This code:

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

only works in development.
In production (Railway, Heroku, etc.):

  • Django is not designed to serve media files

  • Railway volumes (e.g. /app/media) are not publicly exposed

  • Browser requests to /media/... result in 404 / broken images

So even though:

  • Image uploads correctly

  • product.image.url is returned

  • Frontend sets img.src correctly

…the image cannot be accessed by the browser.


Why mounting a volume does not fix it

MEDIA_ROOT = "/app/media"

Mounted volumes on Railway are private storage, not a public CDN or web server.
Django still has no way to serve those files to the client.


Correct solution (production)

Use external object storage for media files:

  • Cloudinary (easiest)

  • AWS S3

  • Firebase Storage

Example (Cloudinary):

pip install cloudinary django-cloudinary-storage
DEFAULT_FILE_STORAGE = 'cloudinary_storage.storage.MediaCloudinaryStorage'

Then:

product.image.url

returns a public HTTPS URL, which works in production.

Key takeaway

Django should never be used to serve uploaded media in production.
On Railway, use S3 or Cloudinary instead.

Вернуться на верх