as Django newby I am strugling to get an image on screen. After reading tons of questions and answers to problems alike, I am only more puzzled, because it looks like I coded the necesary, but I get an 404 error when clicking on an image link in the admin page or trying to show an image in a template. While the two seem related I will stick to the admin site.
This is what I am seeing in the admin site:
To me it looks correct from what I have seen/read.
But when I click the link I get a 404 error:
Altough the media URL seems to work, because the images/Presentation_....jpg is now prefixed by http://.../media/
The image is in the following directory:
Where C:\Users\Admin\PycharmProjects\website_andalucia is my BASE_DIR (when I print it from settings.py)
The necesary code looks like this:
My_project/catalog/settings.py
DEBUG = True
...
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
# Base url to serve media files
MEDIA_URL = '/media/'
# Path where media is stored
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
print("base dir:", BASE_DIR)
print("media root:", MEDIA_ROOT)
My_project/my_project/models.py (see the remark_image)
class remark(models.Model):
# Fields
activity = models.ForeignKey(activity, on_delete=models.CASCADE, null=True)
remark_date = models.DateField(default=date.today)
remark_desc = models.TextField(help_text='Enter your remark(s) here')
remark_image = models.ImageField(upload_to='images/', null=True, blank=True)
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
My_project/catalog/urls.py
urlpatterns = [
path('', views.index, name='index'),
path('activities/', views.activitiesView.as_view(), name='activities'),
path('activity/<int:pk>', views.activityDetailView.as_view(), name='activity-detail'),
path('my_activities/', views.userActivitiesView.as_view(), name='my_activities'),
path('add_activity/', views.add_activity, name='add_activity'),
path('activity/<int:pk>/add_remark/', views.add_remark, name='add_remark'),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
My_project/my_project/urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', RedirectView.as_view(url='catalog/', permanent=True)),
path('catalog/', include('catalog.urls')),
path('accounts/', include('django.contrib.auth.urls')),
]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Why do I get the 404 error message instead of the image?
PS I am on Windows 10, using PyCharm, Python 3.11.0 and a venv with Django 4.1.5
You need to include all urlpatterns from all the secondary urls.py files into final, main urlpatterns
set in the main project urls.py
file.
Example from the docs:
urlpatterns = [
path("index/", views.index, name="main-view"),
path("bio/<username>/", views.bio, name="bio"),
path("articles/<slug:title>/", views.article, name="article-detail"),
path("articles/<slug:title>/<int:section>/", views.section, name="article-section"),
path("blog/", include("blog.urls")), ### <<<--- here /blog/urls.py is included
...,
]
in case of my_project/app/urls.py
it will be path("", include("app.urls"))
in the my_project/urls.py
upd
this include
path('catalog/', include('catalog.urls')),
means that all the urls from catalog/urls.py
are supposed to be prefixed by catalog/
. That's why Django is unable to map /media/...
to any urlpattern - there is no such url pattern registered, there is only /catalog/media/...
url pattern.
I guess the rest of catalog
app urls are really supposed to be under /catalog/
URL, but media files and media files url pattern are global things, common to the whole project thus it is better to move (not copy) media url pattern to the place where static files url pattern is defined:
My_project/my_project/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)