Mark1982
Mark1982

Reputation: 23

Python Django Filefield 404

Got a interesting issue outside my capabilities. Have searched the whole interwebz but could not find anything suitable. Here we go.

The issue: The GET image file returns 404. In this particular case the file is uploaded using the model filefield. The call made from the template differs from the physical location of the file which, well a 404. Due to the dynamic pattern of the app I am confused how to approach this. In short, I need some help ?!?!

Python Django latest versions, good start.

Project: MySite

App: Main

Model:

class Product_images(models.Model):
    product = models.ForeignKey(Products, on_delete=models.SET_NULL, blank=True, null=True)
    image = models.FileField(upload_to='productimages/', null=True)
    name = models.CharField(max_length=50,unique=False,blank=True)

class Meta:
    verbose_name = 'Product Image'
    verbose_name_plural = 'Product Images' 

def __str__(self):
    return '{} - {} - {}'.format(self.pk, self.product, self.name)

View:

def products_view(request, *args, **kwargs):
    return render(request, "products.html")

products.html:

Includes tag {{ product_section }}

context_processors.py:

Lots of loops and coding here, the important bit is.

html_value += u'<img class="d-block w-100" onclick="openModal();currentSlide(1)" src="{}" width="400px" height="250x" alt="{}">'.format(productimages_obj.image,productimages_obj.name)

The productimages_obj is the queryset

the html value is used within the products.html template

url.py:

urlpatterns = [
    path('home/', views.home_view, name='home'),
    path('products/someproduct', views.products_view, name='some product'),     
]

Outcome:

http://127.0.0.1:8000/products/someproduct [12/Sep/2020 01:02:37] "GET /products/productimages/Finance1.png HTTP/1.1" 404 3228

I understand why the get fails. Simply as the model filefield stores the images under main\productimages. What I cant get my head around is how to ignore the /product/ url prefix.

Would like to get understanding why django behaves in this way. Why the prefix url? and how should i structure my app to circumvent this?

Cheers.

Upvotes: 2

Views: 1002

Answers (3)

GAEfan
GAEfan

Reputation: 11370

This code:

image = models.FileField(upload_to='productimages/', null=True)

uploads the files to MEDIA_ROOT/productimages. So, you want to make sure you have MEDIA_ROOT set in settings.py:

MEDIA_ROOT = '/path/to/products/'
MEDIA_URL  = '/products/'

Then, in urls.py:

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = patterns('',
    # ... the rest of your URLconf goes here ...
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

If you want to use {{ MEDIA_URL }} in your templates, add 'django.template.context_processors.media' in the 'context_processors' option of TEMPLATES. Example:

TEMPLATES = [
{
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': [],
    'APP_DIRS': True,
    'OPTIONS': {
        'context_processors': [
            'django.template.context_processors.media',
        ],
    },
},
]

MEDIA_xxx are usually reserved for user-uploaded images. Read more at:

https://docs.djangoproject.com/en/3.1/ref/models/fields/

Upvotes: 2

Oluwatobi Emmanuel
Oluwatobi Emmanuel

Reputation: 1

Check if you've added your MEDIA_URL and MEDIA_ROOT.

And also try getting the image using product_obj.image.url I guess

Upvotes: 0

Mark1982
Mark1982

Reputation: 23

Not really following your solution. Apologies if I am being thick. The file reference is generated within an custom context tag. Its directly extracted from the filefield. This does not result in Finance1.png. Instead it will reference to productimages/Finance1.png.

Upvotes: 0

Related Questions