I am trying to display images that have been uploaded by the user, but no matter what I try I am getting the broken link icon. I have searched and searched through the documentation, on SO and elsewhere for a couple of days now to no avail. I am new to Django and currently in development so I'm sure I've made some other rookie mistakes, but right now the only thing I care about is displaying uploaded images in templates.
Here are the relevant snippets of my code:
settings.py
MEDIA_URL = '/media/media_root/'
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "media", "media_root")
urls.py
urlpatterns = [
url(r'^admin/?', admin.site.urls),
url(r'^accounts/', include('registration.backends.simple.urls')),
url(r'^about/?', profiles.views.about, name='about'),
url(r'^properties/single/?', properties.views.single, name='single_mens'),
url(r'^properties/married/?', properties.views.married, name='married'),
url(r'^properties/add/add_photos/?', properties.views.add_photos, name='add_photos'),
url(r'^properties/add/?', properties.views.add_rental, name='add_rental'),
url(r'^', profiles.views.home, name='home'),
]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += staticfiles_urlpatterns()
models.py
class RentalPicModel(models.Model):
def __unicode__(self):
return self.image.url
image = models.ImageField(upload_to="pics/originals/", null=True)
rental = models.ForeignKey(RentalModel, on_delete=models.CASCADE)
forms.py
class AddPhotosForm(forms.ModelForm):
class Meta:
model = RentalPicModel
fields = ['image', 'rental']
def clean_image(self):
return self.cleaned_data['image']
def clean_rental(self):
return self.cleaned_data['rental']
views.py
def add_photos(request):
form = AddPhotosForm
current_rental = None
current_photos = []
if request.method == "POST":
form = AddPhotosForm(request.POST, request.FILES)
if request.POST.get('another'):
if form.is_valid():
cleaned_image = form.cleaned_data['image']
cleaned_rental = form.cleaned_data['rental']
current_rental = cleaned_rental
pic = RentalPicModel(image=cleaned_image, rental=cleaned_rental)
pic.save()
current_photos = RentalPicModel.objects.filter(rental=current_rental)
current_photos = [rental.image for rental in current_photos]
for photo in current_photos:
print photo
context = {
'form' : form,
'photos' : current_photos,
}
return render(request, "add_photos.html", context)
Here the output of the print statement (after uploading one photo) is: pics/originals/DSC_1376.jpg and I can see the file is saved to that location.
add_photos.html
<div class="container">
<h1>Upload your photos here.</h1>
<br>
<div class='row'>
<form method="POST" action="" enctype="multipart/form-data"> {% csrf_token %}
{{ form|crispy }}
<div class='col col-xs-3'></div>
<div class='col col-xs-3'>
<input class="btn btn-block btn-info" name="another" type="submit" value="Save and Add Another">
</div>
<div class='col col-xs-3'>
<input class="btn btn-block btn-primary" name="finish" type="submit" value="Save and Finish">
</div>
<div class="col col-xs-3"></div>
</form>
</div>
{% if photos|length > 0 %}
<h2>Uploaded photos:</h2>
{% for photo in photos %}
<div class='row'>
<img src="{{ photo.url }}" alt="">
</div>
{% endfor %}
{% endif %}
</div>
When I inspect the <img> element, I see src="/media/media_root/pics/originals/DSC_1376.jpg" which gives me a url of http://127.0.0.1:8000/media/media_root/pics/originals/DSC_1376.jpg. This seems to be the correct file location to me, but it is still not displaying.
Like I say, everything seems to me to be set up how it is described in the Django documentation and in every other question I've read on SO. What am I missing?
Thank you in advance.
EDIT
Do I need to modify my STATICFILES_DIRS setting at all for uploaded media? Here is what I have right now:
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static_files"),
)
which is where I've put all my CSS and javascript files.
You forgot to concatenate the MEDIA_URL and the {{ photo.url }}.
Try:
<img src="{% get_media_prefix %}{{ photo.url }}" alt="">
More about {% get_media_prefix %} HERE in the docs.
My urls were the problem. When it was trying to retrieve the media files, it matched url(r'^', profiles.views.home, name='home') before it matched any of the media urls. A simple $ fixed it:
url(r'^$', profiles.views.home, name='home')
Related
I'm new to Django.
Trying to build an app that adds two names. Pretty Basic.
Built a page that collects the names but not printing the final result.
Here is my code:
urls.py - inside the app
urlpatterns = [
path('',views.home, name='home'),
path('add',views.addname,name='add')
]
views.py
from django.shortcuts import render
from django.http import HttpResponse
def home(request):
return render(request,'input.html')
def addname(request):
val1 = (request.POST['fname'])
val2 = (request.POST['lname'])
res = 'Hi' + val1 +val2
return render(request, 'resultprint.html',{'resultprint':res})
templates/input.html
{% block content %}
<h1>Hello!</h1>
<form action='addname' method='post'>
{% csrf_token %}
Enter 1st name : <input type='text' name='fname'><br>
Enter 2nd name : <input type='text' name='lname'><br>
<input type='submit'>
</form>
{%endblock%}
templates/resultprint.html
{% block content %}
Result: {{resultprint}}
{%endblock%}
Below are the screenshots:
Couldn't really find where is the mistake happening.
I added the templates and app in the Settings file.
You have to set the same url in your urls.py :
urlpatterns = [
path('', views.home, name='home'),
path('addname', views.addname, name='addname')
]
But you can use directly the name of the url in your html file like that :
{% block content %}
<h1>Hello!</h1>
<form action='{% url 'addname' %}' method='post'>
{% csrf_token %}
Enter 1st name : <input type='text' name='fname'><br>
Enter 2nd name : <input type='text' name='lname'><br>
<input type='submit'>
</form>
{%endblock%}
I am building an app where users can access their archives through a simple slug, as follows:
lekha.cc/<archive_slug>
This is exactly as instagram does it. However, whenever I go to any other page, such as
lekha.cc/dashboard
The code for the archive view runs, saying that it has not found an archive with that slug. This is an issue for 2 reasons: we dont want any excess code to run, and if a user chooses to name their archive 'dashboard', the entire website would potentially break down since no one would be able to access their dashboard.
My urls.py folder is as follows:
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('main.urls'), name='index'),
path('onboarding/', account_views.onboarding, name='onboarding'),
path('register/', account_views.register, name='register'),
path('login/', auth_view.LoginView.as_view(authentication_form=LoginForm, template_name='accounts/login.html'), name="login"),
path('logout/', account_views.logout_view, name='logout'),
path('dashboard/', archival_views.dashboard, name='dashboard'),
path('account_settings/', account_views.account_settings, name='account_settings'),
path('<str:slug>/', main_views.archive, name='archive'),
path('item/<str:slug>/', main_views.work, name='work'),
]
Does anyone have any solutions to this issue?
EDIT:
Here is the code for the dashboard view
def dashboard(request):
user = get_current_user()
archive = Archive.objects.get(creator=user)
filesystem = Folder.objects.get(archive=archive)
if request.method == "POST":
if 'addCategory' in request.POST:
category_name = request.POST['folderName']
filesystem = Folder.objects.get(pk=filesystem.pk)
filesystem.add_child(name=category_name)
return render(request, "archival/dashboard.html", {'filesystem': filesystem, "archve": archive, "fileSystemParse": filesystem.get_annotated_list()})
And the archive view
def archive(request, slug):
# retrieve archive with the corresponding slug requested (lekha.cc/dhruva will return the archive with slug='dhruva')
archive = Archive.objects.get(archive_slug=slug)
filesystem = Folder.objects.get(archive=archive)
return render(request, 'archive.html', {'archive': archive, 'filesystem': filesystem})
And the dashboard template:
<html lang="en">
<head>
<style>
</style>
</head>
</html>
{% extends 'navbar.html' %}
{% block content %}
{% load static %}
<div style="height: 200px; width: 100%;"></div>
<p>
archive: {{ archive.archive_slug }}, filesystem: {{ filesystem.name }}
</p>
<div id="folder_view">
{% include 'partials/folder_view.html' %}
</div>
<input type="button" value="addFolder">
<input type="button" value="addFile">
<form action="/dashboard/" method="post">
{% csrf_token %}
<input type="text" name="folderName">
<input type="submit" value="Add Category" name="addCategory">
</form>
<!-- Popups -->
<div id="new_folder_popup" class="dashboard-popup">
<div class="dashboard-popup-content">
<span class="close">×</span>
<!-- <form action="/dashboard/" method="post">
{% csrf_token %}
<input type="text" name="folderName">
<input type="submit" value="Add Category" name="addCategory">
</form> -->
</div>
</div>
The issue was caused by the browser requesting /favicon.ico/ which django was passing through my view. The url.py file should in theory look through all the URLs in order until it finds the right view, so by default django already checks URLs only once.
The real issue is described further here
I'm trying to make django form to appear after user is logged in and authenticated but the form just does not appear on the page here is my code. I'm stuck on this for few days now and any help would be huge help
Views.py form code
def prasymas(request):
context = initialize_context(request)
user = context['user']
form = Prasymas(request.POST or None)
if form.is_valid():
form.save()
context ={
'form':form
}
return HttpResponseRedirect(reverse('home'))
urls.py code
from django.urls import path
from . import views
urlpatterns = [
# /
path('', views.home, name='home'),
# TEMPORARY
path('signin', views.sign_in, name='signin'),
path('signout', views.sign_out, name='signout'),
path('callback', views.callback, name='callback'),
path('prasymas', views.home, name='prasymas'),
]
template.py code
{% extends "loginas/layout.html" %}
{% block content %}
<div class="container">
<h1 class="d-flex justify-content-center"></h1>
<p class="d-flex justify-content-center"></p>
{% if user.is_authenticated %}
<h4>Sveiki {{ user.firstname }} {{user.surname}}
</h4>
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-secondary">POST</button>
</form>
{% else %}<div class="d-flex justify-content-center">
Prisijungti
</div>
{% endif %}
</div>
{% endblock %}
From your urls.py it looks like the prasymas function in views.py is not being called.
Try making the following change to your urls.py file to include a call to the prasymas function.
Note: the line path('prasymas', views.prasymas, name='prasymas'), now points to views.prasymas not home. This means the path /prasymas will now render your form.
from django.urls import path
from . import views
urlpatterns = [
# /
path('', views.home, name='home'),
# TEMPORARY
path('signin', views.sign_in, name='signin'),
path('signout', views.sign_out, name='signout'),
path('callback', views.callback, name='callback'),
path('prasymas', views.prasymas, name='prasymas'),
]
I'm preparing a blog component of a site, it is created inside an app of a project. It seems that there is no problem except the images are not displayed.
while running, all things are OK, but just the image "alt" is displayed instead of the image. I have images without problem in other pages of this project.
There is a report on Terminal:
"Not Found: /article/static/images/growth_EWAl68g.png
[14/Apr/2019 17:44:38] "GET /article/static/images/growth_EWAl68g.png HTTP/1.1" 404 6164"
As you can see, Django uses a false address (static folder is located in root of projects) to access the images.
class BlogArticle(models.Model):
title = models.CharField(max_length=150)
headline = models.CharField(max_length=300)
body = models.TextField()
post_image = models.ImageField(upload_to ="static/images")
date = models.DateTimeField(auto_now_add=True)
author = models.CharField(max_length=100)
def __str__(self):
return self.title
class ArticleListView(ListView):
model = BlogArticle
template_name = 'article_list.html'
urlpatterns = [
path('', views.HomeView, name= 'home'),
path('article/', views.ArticleListView.as_view(), name='article_list'),
path('article/<int:pk>/', views.ArticleDetailView.as_view(), name='article_detail'),
.
.
.]
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('accounts/', include('allauth.urls')),
path('contactus', include('sendemail.urls')),
path('', include('myapp.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
{% block content %}
<div <div class="container mt-5 bg-light">
{% for article in object_list %}
<div class="form-row">
<div class="form-group col-sm-9 ">
<div class="post-entry">
<h5 > <a href = "{% url 'article_detail' article.pk %}" > {{ article.title }}</a></h5>
<div>
<p class="font-weight-bold"> {{article.headline }} </p>
</div>
<div>
<span class="text-muted">by {{article.author }} | {{ article.date|date:"M d, Y"}}</span>
</div>
</div>
</div>
<div class="form-group col-sm-3 ">
<div class="thumbnail">
<img src="{{article.post_image}}" width=100 height=100 class="rounded" alt="{{article.title}}">
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock content %}
.
DEBUG = True
ALLOWED_HOSTS = []
.
.
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'),]
.
.
I can't understand this condition, It seems that Django should go to static/images/ but it has an extra word (article) at the beginning of the address.
This problem was simply solved by adding
urlpatterns +=static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
to project's urls.py and
MEDIA_URL = '/media/'
in settings.py.
I'm having difficulties in displaying the images that I upload from admin page for each question. In the admin page of Question, I upload image for each question and it's saved in correct directory. However, in the public view, I can't display these images for each question (each question will have a different image based on what I uploaded). [example attached]
Below are the code:
models.py
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
image_movie = models.ImageField(upload_to='static/polls/images', default='static/polls/images')
views.py
def image(request):
images = Question()
var = RequestContext(request,{
'images':images
})
return render_to_response('detail.html', var)
detail.html
<form action="{% url 'polls:vote' question.id %}" method="post">{% csrf_token %}
<img src="{{ question.image_movie.url }}" />
{% for choice in question.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
{% endfor %}
<input type="submit" value="Vote" />
</form>
polls/urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
url(r'^(?P<pk>[0-9]+)/static/polls/images/', views.DetailView.as_view(), name='detail'),
url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'),
url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
]
I tried to find solutions in other places as well but I don't get it and can't apply to my problem. They are:
Django - How can I display a photo saved in ImageField?
Django - Display ImageField
I would really appreciate if you can help me to point out what I did wrong.
Thank you.
I fixed this problem by changing the code of detail.html to:
{% load staticfiles %}
<img src="{% static question.image_movie.url %}" style="width:500px;height:320px"/>
It means the images will be saved and loaded in /static/polls/images. (For example: "127.0.0.1/static/polls/images" instead of "127.0.0.1/polls/1/static/polls/images" as before)
The system seems to not recognise "question.id" to display the images from the directory.