Django Image Upload working but not General File - django

I am facing a situation where I am able to upload Images, but not general files. I am using javascript to track the progress, which says file upload is successful, but file is not there in the media folder. When I do that for images, it works.
Basically, image upload was working, and I tried to copy the same thing and do it for general file upload. Here is the code below.
Models
class Upload(models.Model): # image upload model
image = models.ImageField(upload_to='images')
def __str__(self):
return str(self.pk)
class FileUpload(models.Model): # file upload model
video = models.FileField(upload_to='fileuploads/')
def __str__(self):
return str(self.pk)
Forms:
class UploadForm(forms.ModelForm):
class Meta:
model = Upload
fields = ('image',)
class FileUploadForm(forms.ModelForm):
class Meta:
model = FileUpload
fields = ('video',)
Views:
def home_view(request):
form = UploadForm(request.POST or None, request.FILES or None)
if request.is_ajax():
if form.is_valid():
form.save()
return JsonResponse({'message': 'hell yeah'})
context = {
'form': form,
}
return render(request, 'uploads/main.html', context)
def file_view(request):
form = FileUploadForm(request.POST or None, request.FILES or None)
if request.is_ajax():
if form.is_valid():
form.save()
return JsonResponse({'message': 'hell yeah'})
context = {
'form': form,
}
return render(request, 'uploads/main1.html', context)
The HTML template for Image Upload
{% extends "uploads/base.html" %}
{% block content %}
<div id="alert-box"></div>
<div id="image-box"></div>
<br>
<form action="" id="upload-form">
{% csrf_token %}
{{form.as_p}}
</form>
<br>
<div id="progress-box" class="not-visible">progress</div>
<div id="cancel-box" class="not-visible">
<button id="cancel-btn" class="btn btn-danger">cancel</button>
</div>
{% endblock content %}
The only difference with html template for File upload is
{% extends "uploads/base1.html" %}
Which I use a different base html template.
Settings:
STATIC_URL = '/static/'
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR,'static')
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
MEDIA_URL = "/media/"
I am using the code from here - https://github.com/hellopyplane/Progress-bar

The javascript code uses a hardcoded field "image", which is called "video" in your second form.

Related

Tags are not being stored in the database even after saving form in django

views.py
def post(request):
if request.method == 'POST':
form = PostModelForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.user = request.user
post.save()
# using the for loop i am able to save the tags data.
# for tag in form.cleaned_data['tags']:
# post.tags.add(tag)
images = request.FILES.getlist('images')
for image in images:
ImagesPostModel.objects.create(post=post, images=image)
return redirect('/Blog/home/')
else:
form = PostModelForm(request.POST)
return render(request, 'post.html', {'form': form})
models.py
class PostModel(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
date_time = models.DateTimeField(auto_now_add=True)
title = models.TextField(null=True)
body = models.TextField(null=True)
tags = TaggableManager()
def __str__(self):
return str(self.user)
post.html
{% extends 'base.html' %}
{% block content %}
<form action="{% url 'post' %}" enctype="multipart/form-data" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="file" multiple name="images">
<input type="submit">
</form>
{% endblock %}
After giving the input the data is stored in the tags field but, not saving in the database.
I can manually insert data through the admin panel successfully but not as a non-staff user.
I have installed taggit and placed it in the installed_apps in settings.py.
Tags are being saved using post.tags.add(tag) inside for loop. What is the issue with the code?
This is because you use commit=False for the form: then the form has no means to save the many-to-many fields. It is also not necessary to do that, you can work with:
def post(request):
if request.method == 'POST':
form = PostModelForm(request.POST)
if form.is_valid():
form.instance.user = request.user # set the user
post = form.save() # save the form
ImagesPostModel.objects.bulk_create([
ImagesPostModel(post=post, images=image)
for image in request.FILES.getlist('images')
])
return redirect('/Blog/home/')
else:
form = PostModelForm()
return render(request, 'post.html', {'form': form})
Note: Models normally have no Model suffix. Therefore it might be better to rename PostModel to Post.
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.

Django get file url

I want to show the URL, filename and size of the uploaded file on my site.
I tried object.file.url but it didn't work.
models.py:
file = models.FileField(upload_to="media/",null=True,blank=True, verbose_name="Files", validators=[
FileExtensionValidator(allowed_extensions=['pdf', 'docx', 'doc', 'xlsx', 'xls', 'png','jpg','jpeg'])])
And tried this but not working:
in models.py:
#property
def file_url(self):
if self.file and hasattr(self.file, 'url'):
return self.file.url
You didn't give enough information to solve this issue . Where is your views.py and templates/filename.html file code ?
Since you didn't give enough information so I try to answer your question by using another example.
Suppose your models.py file is look like in the below :
models.py
class Pic(models.Model):
name = models.CharField(max_length=255)
photo = models.FileField(upload_to="data/media/%Y/%m/%d")
def __str__(self):
return self.url
def path(self):
return self.url
And also your views.py is look like in the below:
views.py
def upload_pic(request):
documents = Pic.objects.all()
import uuid
name = uuid.uuid4().hex[:6].upper()
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
print(request.FILES)
newdoc = Pic(name=name, photo=request.FILES['docfile'])
newdoc.save()
return render(request, 'clinic/list.html', {'documents': documents, 'form': form, 'msg': 'success'})
else:
form = DocumentForm() # A empty, unbound form
return render(request, 'clinic/list.html', {'documents': documents, 'form': form})
In that case , you can show your uploaded file's url by using {{ document.photo.url }} that line of code in your template file . just check out the below example :
<!-- List of uploaded documents -->
{% if documents %}
<ul>
{% for document in documents %}
<li>{{ document.photo.name }}</li>
{% endfor %}
</ul>
{% else %}
<p>No documents.</p>
{% endif %}

Load the csv data using html view into django database

I am trying to load a simple csv file into django model named as class Team
class Team(models.Model):
Team = models.CharField(max_length=255,primary_key=True)
Description = models.CharField(max_length=255)
def __str__(self):
return self.Team
Views.py
def model_form_upload(request):
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('home')
else:
form = DocumentForm()
return render(request, 'core/model_form_upload.html', {
'form': form
})
HTML
{% block content %}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Upload</button>
</form>
<p>Return to home</p>
{% endblock %}
forms.py
class DocumentForm(forms.ModelForm):
class Meta:
model = Document
fields = ('description', 'document', )
I have create a simple html page to load the file into the following location MEDIA_ROOT=os.path.join(BASE_DIR,"media")
I am able to load my file into that location but I need some help with passing on the data to the actual database and load the values into the table "Team". Any suggestiond on this?

Django: upload image can't find uploaded image

I have already tried searching stackoverflow, but couldn't find anything. My problem is that I cannot seem to find the folder where the pictures I upload is supposed to be. Seems like everything else works?
Here you can see my code:
Settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Views.py
#login_required(login_url="/login/")
def model_form_upload(request):
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES,instance=request.user)
if form.is_valid():
form.save()
print("Form is valid")
return redirect('/questions/profile')
else:
form = DocumentForm(instance=request.user)
return render(request, 'questions/model_form_upload.html', {
'form': form
})
Urls.py
url(r'^upload/$', views.model_form_upload, name='upload')
Models.py
import os
def get_image_path(instance, filename):
return os.path.join('users/', str(instance.id), filename)
class Document(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
profile_image = models.FileField(upload_to=get_image_path,
blank=True, null=True)
Forms.py
from questions.models import Document
class DocumentForm(forms.ModelForm):
class Meta:
model = Document
fields = ('profile_image',)
model_form_upload.html
{% extends 'questions/base.html' %}
{% block content %}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Upload</button>
</form>
<p>Return to profile</p>
{% endblock %}

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.