Following code work fine to store thumbnails images in /media/ directory. i want to store all images in following directory but django also save images path in database. Please let me know, how i can stop django to save their path and address in database ?
model.py : Code
from django.db import models
class Document(models.Model):
thumbnail = models.ImageField()
views.py : Code
from .models import Document
from .forms import DocumentForm
if (request.FILES['thumbnail']):
newdoc = Document(thumbnail = request.FILES['thumbnail'])
newdoc.save()
forms.py : Code
from django import forms
class DocumentForm(forms.Form):
thumbnail = forms.ImageField(
label='Select a file',
help_text='max. 42 megabytes'
)
template.html : Code
<form action="" method="post" id="imgUpload" enctype="multipart/form-data">
<p>{{ form.non_field_errors }}</p>
<p>{{ form.thumbnail.label_tag }} {{ form.thumbnail.help_text }}</p>
<p>
{{ form.thumbnail.errors }}
{{ form.thumbnail }}
<button type="submit" id="thumbUpload" class="btn btn-success"><i class="glyphicon glyphicon-picture"></i> Upload Thumbnails</button>
</form>
you have to override your form method , before save your validform , or you can handle with your code , you don't need to have model or form you can handle with
image = request.FILES['myfile']
now you have your image you can save it directly without model
example reproduced from Django Documentation.
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
def upload_file(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
handle_uploaded_file(request.FILES['file'])
return HttpResponseRedirect('/success/url/')
else:
form = UploadFileForm()
return render_to_response('upload.html', {'form': form})
def handle_uploaded_file(f):
destination = open('file path', 'wb+')
for chunk in f.chunks():
destination.write(chunk)
destination.close()
you can change 'file path ' with your path where you want to store your image
I'm not clear about what you are trying to achieve but the solution is barely simple. Just get the file object and save...
oh.. one more thing just remove all the thumbnail in models.py and other files...
def handle_uploaded_file(f):
destination = open('your_media_path/media/file.png', 'wb+')
for chunk in f.chunks():
destination.write(chunk)
destination.close()
in your POST view
f = request.FILES['thumbnail']
handle_uploaded_file(f)
Related
I am developing a django app which converts pdf to images.I am using FileField for this purpose and using ModelForms. Once uploaded the pdf files will get converted into .png and stored in a separate folder. The upload and converting pdf to png works fine but now I want to display the converted images.
I know I can use url of the uploaded image to display it but the issue is I am uploading a pdf file and hence cannot use the url to display it. I know how to display an uploaded image using url of that image. But I am uploading a pdf file, converting into image and finally storing it into separate folder. So how can I display the images stored? Below is the code I am using:
forms.py
from django import forms
from django.forms import ClearableFileInput
from app1.models import UserUploadModel
class UserUploadForm(forms.ModelForm):
class Meta:
model = UserUploadModel
fields = ['file']
widgets = {
'file' : ClearableFileInput(attrs = {'multiple': True}),
}
models.py
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class UserUploadModel(models.Model):
user = models.ForeignKey(User, on_delete = models.CASCADE, null = True)
file = models.FileField(upload_to = 'file_uploads')
views.py
from django.shortcuts import render, redirect
from app1.forms import UserUploadForm
from app1.models import UserUploadModel
from app1.convert import convert_file
from app1.transfer import move_dir
import os
from project1 import settings
from django.contrib.auth.decorators import login_required
#login_required
def home(request):
if request.method == 'POST':
form = UserUploadForm(request.POST, request.FILES)
if form.is_valid():
files = request.FILES.getlist('file')
f_list = []
if files:
for i in files:
file_instance = UserUploadModel(file = i, user = request.user)
file_instance.save()
f_list.append(file_instance.file.path)
[convert_file(j) for j in f_list]
src_dir = os.getcwd()
dest_dir = os.path.join(src_dir, 'media/converted_files')
move_dir(src_dir, dest_dir, '*.png')
return redirect('app1-display')
else:
form = UserUploadForm()
return render(request, 'app1/home.html', {'form' : form})
#login_required
def display(request):
images = UserUploadModel.objects.filter(user = request.user)
context = {
'images' : images
}
return render(request, 'app1/display.html', context)
home.html
{%extends "app1/base.html"%}
{%block content%}
<form method="POST" enctype="multipart/form-data">
{%csrf_token%}
{{form.as_p}}
<input type="submit">
</form>
{%endblock content%}
display.html
{%extends "app1/base.html"%}
{%load static%}
{%block content%}
{%if user.is_authenticated%}
<h2>User: {{request.user.username}}</h2>
{%endif%}
{%if images%}
{%for i in images%}
<img src={{ i.file.url }}>
{%endfor%}
{%endif%}
{%endblock content%}
Wrong approach change your model and make a file field for the converted pdf also. After converting save the file to this model field. Then you can get the url of the converted file.
I'm not sure but can you use PIL to open the image and then use Django File Response to return the image.
from PIL import Image
from django.http import FileResponse
def display(request):
images = UserUploadModel.objects.filter(user = request.user)
if images:
image = Image.open(images[0].file.path)
return FileResponse(image, content_type='image/png')
I am trying to send data from django forms to backend sqlite3. But I am unable to do so. I am not also getting any error or warning that help me to sort it out.
Here is models.py file
from django.db import models
GENDER_CHOICES = [
('Male', 'M'),
('Female', 'F')]
class upload(models.Model):
name = models.CharField(max_length=100)
gender = models.CharField(max_length=10, choices=GENDER_CHOICES)
phone = models.CharField(max_length=50,null=True)
email= models.EmailField(max_length=50,null=True)
file=models.FileField(upload_to='uploads/')
def __str__(self):
return self.name
here is forms.py file
from django.forms import ModelForm
from .models import upload
class uploadForm(ModelForm):
class Meta:
model = upload
fields = ['name', 'gender', 'phone', 'email','file']
Here is view.py file
from django.shortcuts import render
from .forms import uploadForm
from django.shortcuts import render
def home(request):
if request.method == 'POST':
form = uploadForm()
if form.is_valid():
form=form.save()
return HttpResponseRedirect('/')
else:
form = uploadForm()
return render(request,'home.html',{'print':form})
I am unable to understand where is the issue
This is how template file look like
<form method="post">
{% csrf_token %}
{{ print.as_p }}
<input type="submit" value="Submit">
</form>
EDIT
This issue is with FileField, I removed it, and it start saving in django database. What I want is to save file in media folder and other data in database
I also added enctype="multipart/form-data" in form
I don't think your actually sending anything to the database.
Where is says form = uploadForm() you need state you want the posted data to be sent. so this needs to be form = uploadForm(request.POST) it should then work I believe. Also when saving the form, remove the form=form.save() and leave it as form.save()
Try it out and let us know?
Solution to my post
For handling files, I need to add encryption type to my form as
enctype="multipart/form-data"
Once I added that, to access the files I should use request.FILES along with request.POST
So now I have this home function in views.py file
def home(request):
if request.method == 'POST':
form = uploadForm(request.POST,request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect('/')
else:
form = uploadForm()
return render(request,'home.html',{'print':form})
and my template form looks like
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ print.as_p }}
<input type="submit" value="Submit">
</form>
Credit : https://youtu.be/Rr1-UTFCuH4?t=244
I just have a upload file form in my django project (I'm using 1.10). Everything is working pretty fine actually, but as people will be uploading a csv file into the server I need to limit my logic into just request the file with a specific name and format.
This is my code:
views.py
def list(request):
# Handle file upload
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
newdoc = Document(docfile = request.FILES['docfile'])
newdoc.save()
# Redirect to the document list after POST
return HttpResponseRedirect(reverse('action'))
else:
messages.add_message(request, messages.ERROR,
'Something went wrong with files! Please contact the system administrator')
return render(request, 'upaction-report.html')
# Load documents for the list page
# Render list page with the documents and the form
return render(request, 'upaction-report.html', {'form': form})
forms.py
class DocumentForm(forms.Form):
docfile = forms.FileField(
label='File format should be under the following format:',
help_text='- .csv format and under the name "Action_Report"',
)
template html
<form action="{% url "list" %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<p>{{ form.non_field_errors }}</p>
<p>{{ form.docfile.label_tag }}</p>
<p> {{ form.docfile.help_text }}</p>
<p>
{{ form.docfile }}
</p>
<p><input type="submit" value="Upload File"/></p>
</form>
Any guess on how applying that limit? In case the file is not the right just to pop up a message telling to try again until it has the right format and name. Thanks for yout time, if you need more details just let me know.
You can validate filename inside DocumentForm clean method like this:
class DocumentForm(forms.Form):
docfile = forms.FileField(
label='File format should be under the following format:',
help_text='- .csv format and under the name "Action_Report"',
)
def clean(self):
docfile = self.cleaned_data.get('docfile')
if not docfile:
raise forms.ValidationError('file is required')
if not docfile.name.startswith('filename'):
raise forms.ValidationError('incorrect file name')
if not docfile.name.endswith('fileformat'):
raise forms.ValidationError('incorrect file format')
return super(DocumentForm, self).clean()
I am a newbie to django and i'm desperate for help uploading and reading excel data without actually saving the data on the machine. I have written some code and taken some from the research i've done online.
These are my questions:
1. How do I Upload an excel file (without it being saved on the machine). I just want the excel file to populate some django fields and not save it.
How do I make django read the columns in the excel file and feeds into some other fields on another page. (How do I link them up?)
Most docs I've seen require me to hard-code the name of the excel file and its locations.IS there a way around this as I don't know where the user might be uploading from.
pls advice.
My views.py:
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from credit.models import Document
from credit.forms import DocumentForm
def list(request):
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
newdoc = Document(docfile = request.FILES['docfile'])
newdoc.save()
return HttpResponseRedirect(reverse('credit.views.list'))
else:
form = DocumentForm()
documents = Document.objects.all()
return render_to_response('credit/list.html',
{'documents': documents, 'form': form},
context_instance=RequestContext(request)
)
My models.py is:
class Document(models.Model):
docfile = models.FileField(upload_to='documents/')
#these are the models I want the excel columns to feed into
policies = DecimalNumberField()
capital = DecimalNumberField()
inflation = DecimalNumberField()
My forms.py is:
import os
import xlrd
IMPORT_FILE_TYPES = ['.xls', ]
class DocumentForm(forms.Form):
docfile = forms.FileField(label='Select a file')
def clean(self):
data = super(DocumentForm, self).clean()
if 'docfile' not in data:
raise forms.ValidationError(_('The Excel file is required to proceed'))
docfile = data['docfile']
extension = os.path.splitext(docfile.name)[1]
if not (extension in IMPORT_FILE_TYPES):
raise forms.ValidationError(u'%s is not a valid Excel file. Please make sure your input file is an Excel file )' % docfile.name)
file_data = StringIO.StringIO()
for chunk in docfile.chunks():
file_data.write(chunk)
data['file_data'] = file_data.getvalue()
file_data.close()
try:
xlrd.open_workbook(file_contents=data['file_data'])
except xlrd.XLRDError, e:
raise forms.ValidationError(_('Unable to open XLS file: %s' % e))
return data
#i do not want to do this (specify the exact file name). Need an alternative
sh = xlrd.open_workbook('documents\june.xls').sheet_by_index(1)
inflation = open("inflation.txt", 'w')
policies= open("policies.txt", 'w')
capital= open("access_to_finance.txt", 'w')
try:
for rownum in range(sh.nrows):
inflation.write(str(rownum)+ " = " +str(sh.cell(rownum, 1).value)+"\n")
policies.write(str(rownum)+ " = " +str(sh.cell(rownum, 2).value)+"\n")
capital.write(str(rownum)+ " = " +str(sh.cell(rownum, 3).value)+"\n")
finally:
inflation.close()
policies.close()
capital.close()
Then I have a list.html file:
{% if documents %}
<ul class="nav nav-tabs">
{% for document in documents %}
<li>{{ document.docfile.name }}</li>
{% endfor %}
</ul>
{% else %}
<p>Click Upload to go to Upload page</p>
{% endif %}
<form action="{% url list %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<p>{{ form.non_field_errors }}</p>
<p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p>
<p>
{{ form.docfile.errors }}
{{ form.docfile }}
</p>
<p><input type="submit" value="Upload" /></p>
</form>
Answer for question 1:
If your upload file is less then FILE_UPLOAD_MAX_MEMORY_SIZE(2.5MB), django puts the uploaded file in memory. If your file is bigger than 2.5MB, you can change FILE_UPLOAD_MAX_MEMORY_SIZE in your settings file
I'm trying to upload csv through django but it's not working..
Code
Views.py
from django.shortcuts import render_to_response
from forms import UploadForm
from django.http import HttpResponseRedirect
def create(request):
if request.method == 'POST':
form = UploadForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect('/success/url/')
else:
form = UploadForm()
return render_to_response('upload.html', {'form': form})
Url.py
urlpatterns = patterns('',
(r'^$', create),
#url(r'^articles/create/$', create, name='done'),
url(r'^articles/create/$', 'article.views.create'),
)
models.py
from django.db import models
from time import time
def get_upload_file_name(instance, filename):
return "uploaded_files/%s_%s" % (str(time()).replace('.','_'), filename)
class Article(models.Model):
file = models.FileField(upload_to=get_upload_file_name)
Forms.py
from django import forms
from models import Article
class UploadForm(forms.ModelForm):
class Meta:
model = Article
html file
{% csrf_token %}
{{form.as_p}}
Your template needs to be:
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" />
</form>
See the binding uploaded files to a form section in the documentation.