Upload in Django - django

I was trying to understand how to upload files using Django, so I used the example (latest version, upload is working):
https://github.com/axelpale/minimal-django-file-upload-example
I have a few Questions now:
How do I set a max file size? (I have checked the documentation of Django, but I don't get it)
Is there a way for me to read the file before the user uploads it?
(i.e a program that checks certain things and if they are ok, it can be uploaded)
Here is some code...
model.py:
class Document(models.Model):
name= models.CharField(max_length=500)
docfile= models.FileField(upload_to='documents/%Y/%m/%d', verbose_name="", validators=[validate_file_size])
def __str__(self):
return self.name + ": " + str(self.docfile)
validators.py:
def validate_file_size(value):
filesize= value.size
if filesize > 20971520:
raise ValidationError("File too big")
else:
return value
views.py:
def uploadView(request):
message = 'Upload your .csv-File'
if request.method == 'POST':
form = documentForm(request.POST, request.FILES)
if form.is_valid():
newDoc = Document(docfile=request.FILES['docfile'])
newDoc.save()
return redirect(uploadView)
else:
message = 'The form is not valid.'
else:
form = documentForm()
documents = Document.objects.all()
context = {'documents': documents, 'form': form, 'message': message}
return render(request, 'upload.html', context)

Related

How to write multiple view function for single page

I'm trying to perform multiple operation for single web page. I'm struggling to write multiple function view for single web page. How to do that. Help me in that.
def home_view(request):
if 'username' in request.session:
if request.method == 'GET':
form = ProfileForm(request.GET)
if form.is_valid:
profile_info = Profile.objects.filter(username=username).values()
for i in profile_info:
profiledict = i
return render(request, 'home/index.html', {'profile_first_name': profiledict['first_name'],
'profile_last_name': profiledict["last_name"],
'profile_phone_number': profiledict['phone_number'],
'profile_email': profiledict['email'],
'profile_address': profiledict['address'],
'profile_image': profiledict['image']})
elif request.method == 'POST':
first_name = request.POST.get('first_name')
last_name = request.POST.get('last_name')
phone_number = request.POST.get('phone_number')
email = request.POST.get('email')
address = request.POST.get('address')
image = request.FILES['images']
file_storage = FileSystemStorage()
obj = Profile.objects.all().filter(username=username)
if len(obj) > 0:
obj.update(first_name=first_name, last_name=last_name, phone_number=phone_number,
email=email, address=address, image=file_storage.save(image.name, image))
return redirect('/home/')
return redirect('/home/')
else:
return redirect('/login/')
def home2_view(request):
if 'username' in request.session:
business_objs = AddBusiness.objects.all().values()
return render(request, 'home/index.html', {'business_objs': business_objs})
else:
return redirect('/login/')
I tried like this, it performing only first operation. Here i'm trying to perform 3 operation, GET(extract data from database and displaying in HTML form), POST(updating the form data), and Displaying all database rows and columns in HTML page.

Django upload form issue, no image selected

i'm trying to solve a little issue with my upload file problem in my django 1.5 application. I downloaded a sort of example, but i have some problem with that.
When i press the ulpoad button it says to me that it's empty, but that it's not true...
this is my upload form:
class DocumentForm(forms.Form):
docfile = forms.FileField(
label='Select a file'
this is the view
def image(request, auction_event_id):
# Handle file upload
try:
auction_event = AuctionEvent.objects.get(pk=auction_event_id)
except AuctionEvent.DoesNotExist:
raise Http404
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('com:auction_view_auction_event', args=(auction_event.pk,)))
else:
form = DocumentForm() # A empty, unbound form
# Load documents for the list page
documents = Document.objects.all()
# Render list page with the documents and the form
return render_to_response(
'auction/setimages.html',
{'documents': documents, 'form': form},
context_instance=RequestContext(request)
)
and the model
class Document(models.Model):
auction_event = models.ForeignKey(AuctionEvent, related_name='images')
docfile = models.FileField(upload_to='documents/%Y/%m/%d')
The usual reason for this is that you've forgotten to add enctype="multipart/form-data" to the HTML form tag. See the docs.

FIle upload with chunks: avoid saving it twice

I use a custom function to upload a file splitting it in chunks, as documented here.
My problem is that calling save() after handle_uploaded_file() uploads my file twice, one into "MEDIA_URL/my_path" dir and one into "MEDIA_URL".
But I would like to have only one upload, the one with chunks.
It is possible to force save() to make 'chunked' upload?
Or should I use different approaches?
Thank you.
models.py
class ShapeFile(models.Model):
name = models.CharField(max_length=100)
srid = models.ForeignKey(SpatialRefSys)
user = models.ForeignKey(User)
color_table = models.ForeignKey(ColorTable)
file = models.FileField(upload_to="my_path")
class Meta:
unique_together = ('name', 'user')
forms.py
class UploadForm(ModelForm):
class Meta:
model = ShapeFile
fields = ('name','user','srid','file','color_table')
widgets = {'srid': TextInput(),
'user': HiddenInput()
views.py
def handle_uploaded_file(fileName, filePath):
with open(filePath, 'wb+') as destination:
for chunk in fileName.chunks():
destination.write(chunk)
#login_required
def shapeIng(request):
if request.method == 'POST':
form = UploadForm(request.POST, request.FILES)
if form.is_valid():
req = request.POST
# Split uploaded file into chunks
fileName = request.FILES['file']
filePath = ShapeFile(file=fileName).file.path
handle_uploaded_file(fileName, filePath)
form.save()
messages.success(request, 'Shapefile upload succesful!')
return redirect('shapeCreated')
else:
messages.error(request, 'Something went wrong uploading Shapefile.')
else: # request.method == 'GET'
form = UploadForm(initial={'user': request.user})
return render_to_response('my_app/base_shapeIngestion.html',
{'form': form},
context_instance=RequestContext(request))
change your view function to this:
def testupload2(request):
if request.method == 'POST':
file_name=request.FILES['file']
form = SomeForm(request.POST, request.FILES)
if form.is_valid():
dest_file = open('C:/prototype/upload/'+ str(file_name), 'wb+')
path = 'C:/prototype/upload/'+ str(file_name)
for chunk in request.FILES['file'].chunks():
dest_file.write(chunk)
dest_file.close()
t = get_template("testupload2.html")
lst = os.listdir('C:/downloads/prototype/prototype/upload/')
html = t.render(Context({'MEDIA_URL':'http://127.0.0.1:8000/site_media/'}))
return HttpResponse(html)

Uploading Profile Image using Django ModelForm

I've looked around at related questions, but none of the answers seem to work. I'm trying to upload a profile image for a user and have it replace (overwrite) the current image. Upon saving the image I want to change the filename to the user id. In it's current form the image will upload, but it won't replace the existing image (e.g. it'll be saved as 2_1.png).
class PhotoForm(forms.ModelForm):
def save(self):
content_type = self.cleaned_data['photo'].content_type.split('/')[-1]
filename = '%d.%s' % (self.instance.user.id, content_type)
instance = super(PhotoForm, self).save(commit=False)
instance.photo = SimpleUploadedFile(filename, self.cleaned_data['photo'].read(), content_type)
instance.save()
return instance
class Meta:
model = UserProfile
fields = ('photo',)
def photo_form(request):
if request.method == 'POST':
form = PhotoForm(data=request.POST, file=request.FILES, instance=request.user.get_profile())
if form.is_valid():
form.save()
else:
form = PhotoForm()
return render(request, 'photo_form.html', {'form': form})
def photo_form(request):
if request.method == 'POST':
form = PhotoForm(data=request.POST, file=request.FILES, instance=request.user.get_profile())
if form.is_valid():
handle_uploaded_file(request.FILES['<name of the FileField in models.py>'])
def handle_uploaded_file(f):
dest = open('/path/to/file', 'wb') # write should overwrite the file
for chunk in f.chunks():
dest.write(chunk)
dest.close()
check here: https://docs.djangoproject.com/en/dev/topics/http/file-uploads/
If that doesn't work, I suppose you could just use os.system to delete the file if the form is accepted. That probably wouldn't be that great of a solution, but it should work.

How to override FileField and automatically delete previous file in Django?

im django beginner (django 1.2.5)
I have that model:
class Document(models.Model):
file = models.FileField(upload_to='documents/%Y/%m/%d', null=True, blank=True)
title = models.CharField(max_length=30)
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
author = models.ForeignKey(User)
#other fields
#other fields
and model form to this:
class DocumentForm(ModelForm):
file = forms.FileField(required=True, error_messages={'required' : 'required!','empty': "empty!"})
title = forms.CharField(widget = forms.TextInput(attrs={'size': 93,}), error_messages={'required': 'required!'})
#other fields
#other fields
class Meta:
model = Document
exclude = ('author',)
def save(self, author, commit=True):
document=ModelForm.save(self,commit=False)
document.author = author
if commit:
document.save()
return document
I uploading new documents in using DocumentForm above and it works pretty but when i trying edit some document i cannot put new file in place previous. I may change every field except FileField.
def document_edit(request, document_id):
doc = get_object_or_404(Document, id=document_id)
form = DocumentForm(instance=doc)
if doc.author == request.user:
if request.method == "POST":
form = DocumentForm(request.POST, request.FILES, instance=doc)
if form.is_valid():
if request.POST.get('cancel'):
return HttpResponseRedirect('/')
elif request.POST.get('delete'):
document = Document.objects.get(id=document_id)
document.file.delete()
document.delete()
return HttpResponseRedirect('/')
else:
form.save(author=request.user)
return HttpResponseRedirect('/')
else:
# return again form with errors
else:
# return form with doc instance
else:
# return "you can't edit this doc!"
I research django documentation and i only know i should write some custom save method in some class but i completely have no idea how can i do this. It should be save() method in Document() or in DocumentForm()?
Generally i want this: When i put path to new file in form i want override this new file in his place and automatically delete previous file.
Can you help me? Thanks in advance!
You are on the right track, you just want to use the instance keyword, so your form reflects the object being edited. Simplified version:
def edit_upload(request, document_id):
doc = get_object_or_404(Document, id=document_id)
if request.method == 'POST': # If the form has been submitted...
form = DocumentForm(request.POST, request.FILES, instance=doc)
if form.is_valid(): # All validation rules pass
if doc.file: # If document has file already...
doc.file.delete() # delete it
form.save() # Saves object, uses new uploaded file
return redirect('/thanks/') # Redirect after success
else:
form = DocumentForm(instance=doc) # Show form to edit
return render(request, 'edit.html', {
'form': form,
})