Am currently working with django and using the forms to render a form different fields. The problem am facing is that I have file field in the form and sometimes when submitting the form and a different field returns an error, the file field "value" disappear, which means must re-select the file again..
Is there a way to maintain the file even when the form returns an error? Any examples I can look at or anything that can help me?
Thanks
See https://github.com/un1t/django-file-resubmit
In Django project you have forms with FileField, ImageField.
Everything works great, but when ValidationError is raised, you have
to reselect all files and images again. It is kind of annoying.
django-file-resubmit solves this problem. It works with FileField,
ImageField and sorl.thumbnail.ImageField.
Related
I am currently digging into django form wizards and I am trying to upload multiple images. Unfortunately, the BaseStorage provided by django form wizard does not handle multiple files. It always assumes a dictionary to be passed. There is a fix posted here.
The problem is now, that the posted code breaks in the render_done step of the form wizard when the form_obj is reevaluated. FileFields do not validate when the file is turned from dict to a list.
Can anybody point me in the correct direction on how to fix this?
How do generic views deal with this issue? Or don't they have this issue at all?
I have a view that handles a POST request and attempts to create a new object. However, I know that some of the POST'd data is invalid... But I want to fix it and go ahead and create the object.
The only way I can figure out to be able to 'fix' data in a ModelForm is to create a 'is_valid()' form. To do this, I can either create the form with the POST data, or I can create it with an already existing instance. Unfortunately, if I use the POST data, because some of it is invalid, the form won't validate and I am thus unable to get to the data in the form to fix it. If I create it with an already existing instance, this works, but when the form is displayed, any remaining errors are for whatever reason ignored (and thus don't show up on the web page.) I've tried a combination of creating the the Model form from the POST data and giving it an instance, but this doesn't seem to help. Additionally, I've tried modifying (a copy of) the POST data, fixing it, and then creating the ModelForm from the 'fixed' POST data. This sort of works, with the exception that I have some ImageFields in my form, and they seem to just be ignored.
Any help would be greatly appreciated. I have looked at every good page that I can find to no avail.
Perhaps there is a better way to do this? The problem I'm trying to solve is that I want to have a model that contains ImageFields. The first time I put up the form, the user needs to 'upload' images for each of the fields. However, if he doesn't update an image for one of the fields, I want the new form to come up with a Image upload button on the fields where images have not been uploaded, and just a text field with the image name for images that have been uploaded.
Edit 9/15/2010:
Ok, I think I can simplify all of the above question into this:
def testing( request ) :
test_form = UserProfileForm()
valid = test_form.is_valid()
return render( 'testing.tmpl', locals(), request )
When the above code is rendered, the 'valid' shows as False (as one might expect), but the 'test_form' renders without any errors. I've read through (if perhaps not understood?) the documentation on Models and ModelForms, and I see that most of the time a ModelForm (in my case: UserProfileForm) is created with a specified 'instance'. However, 1) I don't have an instance yet, 2) I would still expect the non-instance'd Form to display errors. I'm sure there is something I am missing. Please illuminate. :)
One more thing, which perhaps the answer to the above will answer anyway, but as far as I can tell, the is_valid() call is supposed to call the 'clean()' function I defined for the UserProfileForm. However, (not being a python guru) I placed 'raise ValidationError()' at the top of clean(), and when I run the code, no error is shown. Thoughts?
Update: I figured out the problem and the answer is below. Thanks!
You should have a look at how to clean form fields in django. You could either manipulate the data returned from the form there or make any kind of validation!
If your ImageFields are optional then you can still validate them (that they are otherwise correct).
Then it's a matter of adjusting your template to show either the uploaded file name or an file upload field depending on whether they've already uploaded one or not. Actually, it would probably be better to give them both fields in the first case. That's what the automatic admin does (the upload field is labeled "Change").
Well, after figuring out how to use the python debugger (pdb) and the fact that within emacs it kind of 'just works' (wow!?) I was able to find that my (empty) form was not bound. Googling bound forms pointed me to this page:
http://docs.djangoproject.com/en/dev/ref/forms/api/
RTFM'ing I find that I can pass an empty dictionary to my form and then everything starts to behave as I would expect. So, to summarize, there is a big difference between:
test_form = UserProfileForm()
and
test_form = UserProfileForm( {} )
The second version causes the rendering of the form to show all the errors (and to call 'clean()').
With risk of having this deleted by the moderator ;) Thank you to all those who commented and for your patience with a new django developer.
I have a model that inherits from Photologues 'ImageModel'. The user can upload photos and everything works fine, however the problem I am running into is when I am creating a form to edit a photo object. Since the ImageModel.image is a required field, and I can't prepopulate a FileField widget with a file already uploaded, if the user doesn't upload a new image to overwrite the old one they get an error. The error pops up in form.save() which I am using to get the rest of the fields updated right. Is there some way I can hook in and try say "since I know I am just editing an image, I know one has already been uploaded, so don't worry if the form field is empty".
Any thoughts?
You have a couple options. One, you can modify the Photologue source to make that field optional. The other, and if it will work for you the one I'd recommend, is to check out my newer library django-imagekit: http://bitbucket.org/jdriscoll/django-imagekit/wiki/Home
ImageKit is basically JUST the ImageModel part of Photologue but it's much more flexible and easier to work with. ImageKit's ImageModel works on top of the models that you define so fields can be configured how ever you please.
I am implementing an application with django, which has a model with a FileField:
class Slideshow(models.Model):
name = models.CharField(max_length=30,unique=True)
thumbnail = models.FileField(max_length=1000,upload_to="images/app/slideshows/thumbnails")
and I have an admin backend where django manages the models. I just added the file admin.py and django manages everything for me
from django.contrib import admin
from apps.gallery.models import Slideshow
admin.site.register(Slideshow)
In the backend, it is possible to add, delete and update the slideshows. However, when I try to update a slideshow and change its attribute thumbnail [FileField], django does not delete the old file. Consequently, after several updates the server is filled with many files which are useless.
My question is: how can I make django delete those files automatically after an update?
I would really appreciate your help
I thought much about this problem, and eventually I find out a solution than works well for me. You can find all models in project and connect pre_save and post_delete signals to them.
At the end I made app, which sloves this problem - django-cleanup
I'm sure Django does this by design. It can't know, for example, whether any other models might be using that file. You would also be really surprised if you expected the file to remain and discovered that django deleted it!
However, there's also the issue that as soon as you change the file field, you lose the old file name.
There's an open ticket about that problem: http://code.djangoproject.com/ticket/11663
There's a patch in http://code.djangoproject.com/ticket/2983 which shows how to override __set__ to store the previous file name. Then your model's __save__ method can get access to the previous file name to delete it.
UPDATE : thanks to posters below, it's clear that the official documentation is up-to-date. Best to read that carefully rather than skim a bunch of other pages that turn up in Google.
I keep finding examples and snippets for uploading files in Django, but then reading people saying that they're out of date.
Here are my basic confusions (from seeing various examples) around the web.
Do I have to save the file data myself manually (ie. open a file and write it, as in this example) or does Django now save the file automatically when I save a model which has a field of type File?
Do I have to manually get the file data from somewhere in order to copy it in to this field in the model? I mean, I understand that request.FILES is deprecated) but when I upload a file from a custom HTML-form (using a <input type="file" tag) the cleaned_data for this field is None, even though the request.FILES dictionary still seems to contain the data. So how am I meant to pick up the file data and put it into the model's field? (If that's what I'm meant to do?)
cheers
phil
The docs are very good regarding this, and are up-to-date.
For basic file uploading, simply use a FileField in your form. Passing in request.POST and request.FILES to this form will do the work for you. Certainly, request.FILES is not deprecated as far as I can tell.
Now, if you want to do more fancy stuff with your file uploads, that is when you'll have to potentially break away from the default FileField, but again, this is covered quite well in the documentation.
I will also add that one common mistake is forgetting to have enctype="multipart/form-data" in one's form. Not including this results in request.FILES being empty.