File upload in Django - django

I'm trying to get Django to upload a file (keeping it simple, for now), but am having difficulties. Here's all of the relevant code (that I know of). Perhaps something is wrong with my settings.py? My code is pieces of various answers on Stack Overflow. I've checked here already.
When I select a file (~8.5mb file because I saw Django does something funny if it is under 2.5mb) and press Submit, I am brought to the Upload Success page, but can't seem to find my file anywhere in my project directory.
I am using the development runserver with apache running just for serving images.
settings.py
MEDIA_ROOT = '/Users/adam/Documents/workspace/sitename/media'
MEDIA_URL = 'http://127.0.0.1:8000/media/'
STATIC_ROOT = '/Library/WebServer/Documents/static/'
STATIC_URL = 'http://10.0.1.15/static/'
ADMIN_MEDIA_PREFIX = '/media/admin/'
STATICFILES_DIRS = (
)
*the static URL is the address of my local apache webserver.
urls.py
urlpatterns = patterns('',
('^$', index),
('^uploadfile/$', uploadfile),
('^uploadsuccess/$', uploadsuccess),
)
if settings.DEBUG:
from django.views.static import serve
_media_url = settings.MEDIA_URL
if _media_url.startswith('/'):
_media_url = _media_url[1:]
urlpatterns += patterns('',
(r'^%s(?P<path>.*)$' % _media_url,
serve,
{'document_root': settings.MEDIA_ROOT}))
del(_media_url, serve)
views.py
def uploadsuccess(request):
return render_to_response('uploadsuccess.html', {})
class UploadFileForm(forms.Form):
file = forms.FileField()
def uploadfile(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
handle_uploads(request.FILES['file'])
form.save()
return HttpResponseRedirect('/')
else:
form = UploadFileForm()
return render_to_response('fileupload.html', {'form': form}, context_instance=RequestContext(request))
def handle_uploads(file):
logging.debug("upload_here")
if file:
destination = open('/tmp/'+file.name, 'wb+')
for chunk in file.chunks():
destination.write(chunk)
destination.close()
fileupload.html
<html>
<body>
<h1>Upload a file</h1>
<form enctype="multipart/form-data" method="post" action="/uploadsuccess/">
{% csrf_token %}
<table>
{% for field in form %}
{{ field.label_tag }}
{{ field }}
{% endfor %}
</table>
<input type="submit" value="Submit" id="Save"/>
</form>
<body>
</html>
uploadsuccess.html
<html>
<body>
<h1>Upload Successful!</h1>
<body>
</html>

You are posting data to the wrong URL, change action="/uploadsuccess/" to /uploadfile/.

Related

Problem is that image is not saving . when i am select image and upload all code working properly but image does not save django

Problem is that image is not saving. when I am select an image and upload all the code working properly but the image does not save. I checked all the code line by line I do not understand what's the problem. I also see the media file any image is saved or not, but the image wasn't saved.
this is models.py in this file I use the image field
models.py
class Answer (models.Model):
question=models.ForeignKey(Question,on_delete=models.CASCADE)
user=models.ForeignKey(User,on_delete=models.CASCADE, null=True)
img=models.ImageField(null=True,blank=True,upload_to='Answer_Img')
detail=RichTextUploadingField()
add_time=models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.detail
forms.py
class AnswerForm(ModelForm):
class Meta:
model=Answer
fields=('detail','img')
labels={'img':'Upload Image'}
views.py
def answer(request,pk,slug):
try:
trend=Question.objects.get(pk=pk,slug=slug)
except:
raise Http404("Post Does Not Exist")
tags=trend.tags.split(',')
ans=Answer.objects.filter(question=trend)
answerform=AnswerForm
if request.method=='POST':
answerData=AnswerForm(request.POST)
if answerData.is_valid():
answer=answerData.save(commit=False)
answer.question=trend
answer.user=request.user
answer.save()
p=messages.success(request,'Answer has been submitted.')
return HttpResponseRedirect(trend.slug)
return render(request,"ask/answer.html" ,{
'trends':trend,
'tags':tags,
'answer':ans,
'form':answerform,
})
answer.html
{% if user.is_authenticated %}
<div class="container">
<div class="py-5 text-center bg-secondary text-white">
<h1 class="mb-3">Upload Image</h1>
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{form}}
<input type="submit" class="btn btn-danger" value="Upload">
</form>
</div>
{% else %}
<h3><P>Sign In/Sign Up before posting answers</P></h3>
<h4><li>Sign In</li><h4>
<h4> <li>Sign Up</li><h4>
{% endif %}
settings.py
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
urls.py
urlpatterns = [
# my url patterns here
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root = settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
Use request.files to get the img. please check if the media folder is in your base directory and the subfolder is named correctly.
if request.method == "POST":
answer_form = Answer_form(data=request.POST)
if(answer_form.is_valid()):
ans = answer_form.save(commit=False)
#ans.user = user
if 'img' in request.FILES:
ans.img = request.FILES['img']
ans.save()
else:
print(answer_form.errors)
Here is the documentation page :
File Uploads

Photo not displaying in django html

I spent a few hours trying to find out what is going on but I can`t see why the photo is not displayed in my html file.
Goal: Display the profile photo of each user
Issue: Photo not displaying in django html
detail.html
<div class="col-sx-1 col-sm-5 text-right">
<a href="{% url 'contacts:detail' contact.id %}">
{% if contact.photo %}
<img src="/{{ contact.photo.url }}" class="img-responsive">
{% else %}
<h3>No image to display</h3>
{% endif %}
</a>
</div>
views.py
def create_contact(request):
form = ContactForm(request.POST or None, request.FILES or None)
if form.is_valid():
contact = form.save(commit=False)
contact.user = request.user
contact.photo = request.FILES['photo']
file_type = contact.photo.url.split('.')[-1]
file_type = file_type.lower()
if file_type not in IMAGE_FILE_TYPES:
context = {
'contact': contact,
'form': form,
'error_message': 'Image file must be PNG, JPG, or JPEG',
}
return render(request, 'contacts/create_contact.html', context)
contact.save()
return render(request, 'contacts/detail.html', {'contact': contact})
context = {
'form': form,
}
return render(request, 'contacts/create_contact.html', context)
urls.py
urlpatterns = [...]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
models.py
class Contact(models.Model):
photo = models.ImageField(upload_to='profileimage', blank = True)
settings.py
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Many Thanks,
I have resolved this issue by adding static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) to the main urls.py file. I hope this help.

My form for uploading photos does not work. Django

When I use the form provided by django admin everything works fine. But after creating my own form, django does not write data to my model. Is something missing in my code?
Models.py
class Offert(models.Model):
name = models.CharField(max_length=50)
file = models.FileField(upload_to='app/documents/')
forms.py
class OffertFormCV(forms.ModelForm):
class Meta:
model = Offert
fields = ( 'name',
'file')
views.py
def my_views(request):
if request.method == 'POST':
form = OffertFormCV(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('app:thank_you_page'))
else:
form = OffertFormCV()
context = {'form': form}
return render(request, 'form_application.html', context)
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('app.urls', namespace='app'))
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
settings.py
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'app/media')
form_application.html
<form method="post">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-primary">Send</button>
</form>
After sending the form, nothing happens. Any help will be appreciated.
You need to add enctype="multipart/form-data" to your form to be able to upload files:
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-primary">Send</button>
</form>

play <audio></audio> file in django template

I've been struggling with this for so long that I'm bordering depression.
I have a model called "Song" that looks like this.
from django.db import models
class Song(models.Model):
title = models.CharField(max_length=100)
songfile = models.FileField()
duration = models.FloatField()
isPlaying = False
def __str__(self):
return self.title
When you upload an mp3 file from the index page, it creates an instance of this model and stores the file in myapp/songdir/ using this view:
def home(request):
if request.method == 'POST':
form = UploadForm(request.POST, request.FILES)
if form.is_valid():
song_title = request.POST.items()[1][1]
song_address = 'upnplay/songdir/' + song_title + '.mp3'
with open(song_address, 'wb+' ) as destination:
for chunk in request.FILES['file'].chunks():
destination.write(chunk)
audio = MP3(song_address)
c = Song(title = song_title, songfile = song_address, duration = audio.info.length)
c.save()
return HttpResponseRedirect('')
else:
form = UploadForm()
c = {'form': form}
c.update(csrf(request))
return render(request, 'index.html', {'form': form})
Then I have a template called "choosesong" that displays a list of songs that I get from the model instances saved:
{% extends 'index.html' %}
{% block content %}
<div class="row">
{% for song in playlist %}
<h3>{{song.title}} -- {{song.duration}}</h3>
{% endfor %}
</div>
{% endblock %}
{% block form %}{% endblock %}
When I click on one of this links, I want a new template to be rendered, with a element that plays the song whose name I clicked. The template that I render is this one:
{% extends 'index.html' %}
{% block content %}
<div class='row'>
{{link}}
<audio controls>
<source src="../../{{ link }}" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
</div>
{% endblock %}
And the view I use to deliver it is the following:
def playAudioFile(request, songtitle):
name = urllib.unquote(songtitle)
song = get_object_or_404(Song, title=name )
return render(request, 'playlist.html', {'link': song.songfile })
For some reason I can't get it to play the song inside the audio element and I don't know what else to try.
Thank you beforehand.
You should add MEDIA_ROOT and MEDIA_URL configuration. It will be easy to handle things. Here is the solution to your problem.
In settings.py:
MEDIA_ROOT=os.path.join(BASE_DIR,"songdir")
MEDIA_URL='/media/'
Also in settings.py add
'django.template.context_processors.media',
in the TEMPLATES option's context_processors.
In project/urls.py:
from django.conf import settings
from django.conf.urls.static import static
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Then you can simply use:
{{link.url}}
instead of hardcoding it in your template file.

What is wrong with my CSV import code in Django?

I have overridden my admin change_list.html
{% extends "admin/change_list.html" %}
{% block object-tools-items %}
<li>
Import CSV
</li>
{{ block.super }}
{% endblock %}
When I click this Import CSV link, I would like to import CSV and save to my model.
App's name Auction. Objects of Auction:
forms.py
from django import forms
import csv
from auction.models import AuctionGroup, AuctionHouse, AuctionList
class DataInput(forms.Form):
file = forms.FileField()
def save(self):
records = csv.reader(self.cleaned_data["file"])
for line in records:
house = AuctionHouse()
house.house_name = line[0]
house.auction_type = line[1]
house.auction_day = line[2]
house.volume = line[3]
house.aleado_id = line[4]
house.aleado_photo_number = line[5]
house.house_region = line[6]
house.save()
views.py
def csv_import(request):
if request.method == "POST":
form = DataInput(request.POST, request.FILES)
if form.is_valid():
form.save()
success = True
context = {"form": form, "success": success}
return render_to_response("auction/importcsv.html", context,
context_instance=RequestContext(request))
else:
form = DataInput()
context = {"form": form}
return render_to_response("auction/importcsv.html", context,
context_instance=RequestContext(request))
urls.py
urlpatterns = patterns('',
url(r'/importcsv/$', views.csv_import, name='importcsv'),
)
project/urls.py
urlpatterns = patterns('',
url(r'^auction/', include('auction.urls')),
url(r'^admin/', include(admin.site.urls)),
)
importcsv.html
<!DOCTYPE html>
<html>
<form enctype="multipart/form-data" method="post" action=".">
{{ form }}
</form>
</html>
But it does not work. Please, help. Regards
Use the {% url %} tag in the link code:
Import CSV
If you want to use single template for multiple models then change_list.html has the cl.opts context variable which is a Model._meta of the current model.
So you can pass the app_label and model_name to your importcsv() view:
<a href="{% url 'importcsv' cl.opts.app_label cl.opts.model_name %}"
class="grp-state-focus addlink">Import CSV</a>
Change your urls.py:
urlpatterns = patterns('',
url(r'/importcsv/(\w+)/(\w+)/$', views.csv_import, name='importcsv'),
)
And the signature of the view function:
def csv_import(request, app_label, model_name):
...