# Media files aren't stored unless uploaded via Django admin

**URL:** <https://forum.djangoproject.com/t/media-files-arent-stored-unless-uploaded-via-django-admin/36917>\
**Category:** Getting Started\
**Created:** [December 3, 2024, 10:16am UTC](https://forum.djangoproject.com/t/media-files-arent-stored-unless-uploaded-via-django-admin/36917 "2024-12-03T10:16:02Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![radhesh](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/radhesh/32/25549_2.png) [@radhesh](https://forum.djangoproject.com/u/radhesh)\
**Post date:** [December 3, 2024, 10:16am UTC](https://forum.djangoproject.com/t/media-files-arent-stored-unless-uploaded-via-django-admin/36917/1 "2024-12-03T10:16:02Z")

</div>

Hi, I’ve been facing a problem with rendering user-uploaded images in my project (in development). I have a form in a template for creating an object for a Model that has an ImageField attribute. However, it does not seem to follow the _upload\_to_ argument. I would appreciate any info on how to fix this.

models.py:

```auto
class Product(models.Model):
    name = models.CharField(max_length=50)
    model = models.CharField(max_length=50)
    version = models.CharField(max_length=20)
    image = models.ImageField(default='products/default.jpeg', upload_to='products/', blank=False, null=False)

    def __str__ (self):
        return self.name

```

views.py:

```auto
def add_product(request):

    if request.method == "POST":
           
        name = request.POST["product_name"]
        version = request.POST["product_version"]
        model = request.POST["product_model"]
        image = request.FILES.get("product_image", None)
        

        product = Product(
            name = name,
            model = model,
            version = version,
            image = image if image else 'products/default.jpeg'
        )
        product.save()

        return HttpResponseRedirect(reverse('products'))
        
    else:
        if request.user.is_authenticated:
            products = Product.objects.all()
            return render(request, 'add_product.html',{
                "products" : products
            })
        
        else:
            return render(request, "login.html", {
                "message": "Login to add products"
            })

```

The form in my template:

```auto
<form class="row gy-2 gx-3 align-items-center" action="{% url 'add_product' %}" method="post">
        {% csrf_token %}
        <div class="col-auto">
            <label for="autoSizingInput">Product Name</label>
            <input type="text" class="form-control" id="autoSizingInput" placeholder="Product name" name="product_name" required>
        </div>
        <div class="col-auto">
            <label for="autoSizingInputGroup">Version</label>
            <div class="input-group">
              <div class="input-group-text"><em>v</em></div>
              <input type="text" class="form-control" id="autoSizingInputGroup" placeholder="Product version" name="product_version" required>
            </div>
        </div>
        <div class="col-auto">
            <label for="autoSizingInput">Model number</label>
            <input type="text" class="form-control" id="autoSizingInput" placeholder="Model number" name="product_model" required>
        </div>
        <div class="col-auto">
            <label for="inputGroupFile02">Product image (optional)</label>
            <div class="input-group">
                <!--<div class="input-group-text">Upload</div>-->
                <input type="file" class="form-control" id="inputGroupFile02" name="product_image">
            </div>
        </div>
        <div class="col-auto">
            <button type="submit" class="btn btn-success">Save</button>
        </div>
    </form>

```

root urls.py:

```auto
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include("RMA_app.urls"))
]

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

```

app urls.py:

```auto
from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name="home"),
    path('login', views.signin, name="login"),
    path('logout', views.signout, name="logout"),
    path('register', views.signup, name="register"),

    path('products', views.products, name="products"),
    path('products/add', views.add_product, name="add_product"),

    path('devices', views.devices, name="device"),
    path('devices/add', views.add_device, name="add_device"),

    path('complaints', views.complaint, name="complaint"),
    path('complaints/add', views.add_complaint, name="add_complaint"),
    path('complaints/<int:complaint_id>', views.view_complaint, name="view_complaint")
]

```

settings.py:

```auto
STATIC_URL = 'static/'
STATICFILES_DIRS = [
    BASE_DIR / 'RMA_app/static',
]
MEDIA_ROOT = BASE_DIR / 'media'
MEDIA_URL = '/media/'

```

When the user creates a Product object by uploading an image, it is saved with the default image with this URL: [http://localhost:8000/media/products/default.jpeg](http://localhost:8000/media/products/default.jpeg) . No image is uploaded to the MEDIA\_ROOT directory. However, when I create a Product object from the admin page, it works as expected by uploading the image to MEDIA\_ROOT and the URL of the image being localhost:8000/media/products/filename.jpeg

I did try changing my view to:

```auto
def add_product(request):

    if request.method == "POST":
           
        name = request.POST["product_name"]
        version = request.POST["product_version"]
        model = request.POST["product_model"]
        
        image_response = request.POST["product_image"]
        if image_response:
            image = image_response
        else:
            image = None
        
        product = Product(
            name = name,
            model = model,
            version = version,
            image = image if image else 'products/default.jpeg'
        )
        product.save()

        return HttpResponseRedirect(reverse('products'))

```

but in this case, the images aren’t uploaded to MEDIA\_ROOT. The URL for the images ended up being [http://localhost:8000/media/filename.jpeg](http://localhost:8000/media/filename.jpeg) and not media/products/filename.jpeg

 ![image](https://us1.discourse-cdn.com/flex026/uploads/djangoproject/original/3X/c/a/ca227d1a6cacee51023e670fcc302edff9d3b18c.png)

Any input would be appreciated. Thank you.

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [December 3, 2024, 1:23pm UTC](https://forum.djangoproject.com/t/media-files-arent-stored-unless-uploaded-via-django-admin/36917/2 "2024-12-03T13:23:04Z")

</div>

Welcome @radhesh !

From the docs at [File Uploads | Django documentation | Django](https://docs.djangoproject.com/en/5.1/topics/http/file-uploads/#basic-file-uploads)

> Note that [`request.FILES`](https://docs.djangoproject.com/en/5.1/ref/request-response/#django.http.HttpRequest.FILES) will only contain data if the request method was `POST` , at least one file field was actually posted, and the `<form>` that posted the request has the attribute `enctype="multipart/form-data"` . Otherwise, `request.FILES` will be empty.

Your `<form ...` element does not show this attribute.

Side note: If you’re posting to the same url from which you got this template, you do _not_ need the `action` attribute in that element. A form will post back to the url from which the page was retrieved.

---

<div class="post-metadata">

**Author:** ![radhesh](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/radhesh/32/25549_2.png) [@radhesh](https://forum.djangoproject.com/u/radhesh)\
**Post date:** [December 4, 2024, 5:39am UTC](https://forum.djangoproject.com/t/media-files-arent-stored-unless-uploaded-via-django-admin/36917/3 "2024-12-04T05:39:46Z")

</div>

Adding the `enctype` attribute to `<form>` solved it. Thanks a lot!
