I want to create user specific folders for files uploaded by users. This is my views.py:
#login_required
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('upload.views.list'))
else:
form = DocumentForm() # An 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(
'upload/list.html',
{'documents': documents, 'form': form},
context_instance=RequestContext(request)
)
This is my models.py:
class Document(models.Model):
docfile = models.FileField(upload_to='uploads/%Y.%m.%d')
My idea is this. Instead of naming it uploads/%Y.%m.%d I stick the username somewhere in there. Is there a way to do that?
I do something like that in my models.py:
def _upload_path(instance,filename):
return instance.get_upload_path(filename)
class Document(models.Model):
docfile = models.FileField(upload_to=_upload_path)
user = models.ForeignKey('auth.User')
def get_upload_path(self,filename):
return "static/uploads/"+str(self.user.id)+"/"+filename
Related
I want to be able to check if the files that are going to be uploaded through forms contain any sensitive information. Can someone please give me an idea on how I can accomplish this.
This is my code.
Models.py
class File(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=100)
doc = models.FileField(upload_to='files/docs/', validators=[FileExtensionValidator(allowed_extensions=['pdf','docx'])])
def __str__(self):
return self.title
My upload code in views.py
def upload_file(request):
if request.method == 'POST':
form = FileForm(request.POST, request.FILES) #request.Files handles file uploads
if form.is_valid():
form.save()
file_dlp()
return redirect('file_list')
else:
form = FileForm()
return render(request, 'upload_file.html', {
'form':form
})
When I upload a photo, the photo is loaded successfully, but the photo is placed in the wrong directory.
Instead of placing the image on the path to 'media/posts-pics/' - as I have outlined in my Post model - it is placed on the 'media' path.
These are my files:
models.py
class Post(models.Model):
index_pic = models.ImageField(upload_to='posts-pics/')
Project.urls.py
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
views.py
def add_post(request):
if request.method == "POST":
form = AddPostForm(request.POST, request.FILES)
if form.is_valid():
new_post = form.save(commit=False)
new_post.index_pic = form.cleaned_data['index_pic']
new_post.save()
return redirect('view_post')
else:
form = AddPostForm()
template = 'post/add_edit_post.html'
context = {'form': form}
return render(request, template, context)
def edit_post(request, slug):
post = get_object_or_404(Post, slug=slug)
if request.method == "POST":
form = AddPostForm(request.POST, request.FILES, instance=post)
if form.is_valid():
Post.objects.filter(id=post.id).update(title=request.POST['title'],
index_pic=form.cleaned_data['index_pic'],
)
return redirect('view_post')
else:
form = AddPostForm(instance=post)
template = 'post/add_edit_post.html'
context = {'form': form}
return render(request, template, context)
I used exactly the same code for add_post, and the photo was in its place, but I got into trouble in edit_post. what's wrong ?
Notice:
Technically I can delete 'media/post-pics' but this is done with a
special purpose and the purpose is: Each app have its folder for
saving images.
The problem is that you're no using your ModelForm the right way.
In the edit_post view, you want to replace this:
Post.objects.filter(id=post.id).update(
title=request.POST['title'],
index_pic=form.cleaned_data['index_pic'],
)
with a plain simple:
form.save()
which will take care of the updating the post passed as form.instance (using sanitized data, which is not the case with your current code)
FWIW, in your add_post view, you also want to replace this
new_post = form.save(commit=False)
new_post.index_pic = form.cleaned_data['index_pic']
new_post.save()
with a plain simple:
new_post = form.save()
Once again, the whole point of ModelForms is that they know how to create and update model instances.
I would like to be able to view my uploaded files. I really have a poor grasp of what I am doing.
views.py
def upload_file(request):
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('learning_logs:topics'))
else:
form = DocumentForm()
return render(request, 'learning_logs/model_form_upload.html', {'form':form})
def file_preview(request):
videos = Document.objects.all()
context = {'videos':videos}
return render(request, 'learning_logs/video.html', context)
models.py
class Document(models.Model):
docfile = models.FileField(upload_to = 'documents/')
upload_at = models.DateTimeField(auto_now_add = True)
forms.py
class DocumentForm(forms.ModelForm):
class Meta:
model = Document
fields = ['docfile']
I have uploaded videos and pictures.
As the files are passed onto the HTML, I can only see the names of the files I uploaded. I can't click on the links and view the files.
I would like to have an actual video player to play the videos, or view the pictures.
Use url attribute of FileField in your template and pass that URL to your favorite player js library.
Getting NameError (global name FileUploadHandler not defined). Here is the model:
class FileUploadHandler(models.Model):
title = models.CharField(max_length=100)
file = models.ImageField(upload_to="wiki/static/")
And the view:
def image_upload(request):
if request.method == 'POST':
form = UploadImageForm(request.POST, request.FILES)
if form.is_valid():
FileUploadHandler(request.FILES['image'])
return render_to_response('wiki/gallery.html')
else:
form = UploadImageForm()
return render_to_response('wiki/gallery.html', RequestContext(request, {'form': form}))
What am I missing?
At the top of your view file, type:
from models import FileUploadHandler
This is assuming you have the standard views.py and models.py file structure where both are in the same directory.
I've created a model form which is then rendered in a context processor as the form is included on every page. Once the form is submitted it should re-direct to a 'thank you' page. However it just seems to re-load the page and remove the form. I had it all working when rendering on a page via a URL. Since moving the function to my context processor it doesn't redirect correctly.
It also saves the information that's provided into the model, in the admin. So I'm guessing it is something to do with redirect.
Here is my context processor:
from django.conf import settings
from contact_enquiries import forms
from django.shortcuts import render
from django.http import HttpResponseRedirect
def contact(request):
if request.method == 'POST':
form = forms.ContactUsForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/thanks/')
else:
form = forms.ContactUsForm()
return {
'contact_form' : form,
}
forms.py
class ContactUsForm(ModelForm):
class Meta:
model = ContactUs
fields = ['name', 'contact_number', 'email', 'enquiry']
models.py
class ContactUs(models.Model):
name = models.CharField(max_length=200)
contact_number = models.IntegerField(max_length=50)
email = models.EmailField(max_length=300)
enquiry = models.TextField()
class Meta:
verbose_name_plural = "Contact Us"
def __unicode__(self):
return self.name
A context processor should always return a dictionary, it shouldn't return an http response.
One option is to make your contact form post to a different view. You do this by changing the action attribute of the form in your template.
<form action="{% url 'contact' %}" method="post">
Your contact view and url patterns would look something like this:
url('^/contact/$', contact, name="contact"),
def contact(request):
if request.method == 'POST':
form = forms.ContactUsForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/thanks/')
else:
form = forms.ContactUsForm()
return render(request, "contact.html", {
'contact_form' : form,
})
Your context processor then simplifies to:
def contact(request):
form = forms.ContactUsForm()
return {'contact_form' : form}