Django - Display images - django

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.

Related

Django - Add two names - Couldn't print results

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%}

how to make sure a certain django url path is only checked if all the other paths have been checked

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

Request.Get in url.py in django

I'm fairly new to Django and have used the tutorial videos of Sir Sentdex in youtube.
I'm trying to integrate a search function in his example but I think he used a different approach in making his example. He didn't use the app's (Product) views.py but instead went straight to url.py
url.py
urlpatterns = [ url(r'^$', ListView.as_view(queryset=Product.objects.all(), template_name="product/product.html"))]
I made a form with search in my header.html and then extends it in product.html .
Here is the code of the form with search:
<form class="navbar-form navbar-right" method='GET' action=''>
<div class="form-group">
<input class="searchfield form-control" id="searchproduct" name="q" type="text" placeholder="Search" value='{{ request.GET.q }}'>
<input type='submit' value='Search'>
</div>
</form>
How can I make the url pattern in the app's url.py like:
query = request.GET.get('q') <- I know this should be in a function.
urlpatterns = [ url(r'^$', ListView.as_view(queryset=Product.objects.filter(
Q(name__contains=query | desc__contains=query )
), template_name="product/product.html"))]
Thanks in advance.

Django 1.9 - Not displaying user uploaded images

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')

Django Template not being rendered correctly using Class based views

I'm a django newbie and wanted to integrate Singly into the django Polls application. I have used class based views to allow for models from the singly app to be passed along with the Polls models.
The problem is, I'm unable to get data from the Singly model even when data is present inside the database.
For now I simply want to display the access_token and profile ID of the user profile.
Here is my Views.py code: (only the view in question)
class IndexView(ListView):
context_object_name='latest_poll_list'
queryset=Poll.objects.filter(pub_date__lte=timezone.now) \
.order_by('-pub_date')[:5]
template_name='polls/index.html'
def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
context['user_profile'] = UserProfile.objects.all()
return context
This is my urls.py:
urlpatterns = patterns('',
url(r'^$',
IndexView.as_view(),
name='index'),
url(r'^(?P<pk>\d+)/$',
DetailView.as_view(
queryset=Poll.objects.filter(pub_date__lte=timezone.now),
model=Poll,
template_name='polls/details.html'),
name='detail'),
url(r'^(?P<pk>\d+)/results/$',
DetailView.as_view(
queryset=Poll.objects.filter(pub_date__lte=timezone.now),
model=Poll,
template_name='polls/results.html'),
name='results'),
url(r'^(?P<poll_id>\d+)/vote/$', 'polls.views.vote', name='vote'),
)
And here is my index.html:
{% load staticfiles %}
<h1>Polls Application</h1>
<h2>Profile Info:</h2>
<div id="access-token-wrapper">
<p>Here's your access token for making API calls directly: <input type="text" id="access-token" value="{{ user_profile.access_token }}" /></p>
<p>Profiles: <input type="text" id="access-token" value="{{ user_profile.profiles }}" /></p>
</div>
<link rel="stylesheet" type="text/css" href="{% static 'polls/style.css' %}" />
{% if latest_poll_list %}
<ul>
{% for poll in latest_poll_list %}
<li>{{ poll.question }}</li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
Its able to fetch Polls correctly but it doesn't print anything in either textboxes i.e. the user_profile.access_token and the user_profile.profiles.
I think the problem is incorrect rendering of the template. It should pass the context 'user_profile' but its not. Or for some reason its not taking the data from the database, because there is an entry in the UserProfile database.
I would be grateful for your help, people.
The user_profile context variable contains list of UserProfile objects. From code:
context['user_profile'] = UserProfile.objects.all() # will return a QuerySet, that behaves as list
And in template it is accessed as if it is a single object:
{{ user_profile.access_token }}
{{ user_profile.profiles }}
So either put to this variable a single UserProfile object in a view. For example:
if self.request.user.is_authenticated()
context['user_profile'] = UserProfile.objects.get(user=self.request.user)
else:
# Do something for unregistered user
Either iterate over profiles in template:
{% for up in user_profile %}
{{ up.access_token }}
{% endfor %}
Either access to profile by index in template:
{{ user_profile.0.access_token }}