Preserve files on editing an object through FormView - django

I've a form that both creates (/new) and edit (/edit/int:pkid).
Editing doesn't override the existing object, but creates a new one instead (so if we edit object id=1, at save it saves as object id=2).
My problem is that I can't get the FileFields to persist, when I submit the edit (POST), the FileFields are reset to None.
I've built a MRE at this address :
https://github.com/Shriukan33/mre_form_with_imagefields
Steps to reproduce error :
Go to http://127.0.0.1:8000/new
Fill the form by providing a title and a first image in file_field
hit save
Go to http://127.0.0.1:8000/edit/1, you should see your form with pre-filled information from previous submission
Add a second image in second_file_field and submit
You should get validation error, stating that if you provide a title, you should also provide an image. I would like the files to persist, as they are present at load, I don't see why they aren't part of the POST.
Thanks !

Related

After saving in a form i want it to point to another site not the forms list

It's probably a stupid question.
I have a form on a custom list that I hade to custom design (the form for editing). But because of the law (GDPR) I can't let the users see the list after they save the form.
One part is sloved by them entering in the form from a page with a direct link to it. But the relinking is not.
This is the original part that I figured I have to change
<SharePoint:SaveButton runat="server" ControlMode="New" id="savebutton2"/>
I changed It to this
<SharePoint:SaveButton RedirectUrl="http://www.google.com" runat="server" ControlMode="New" id="savebutton2"/>
This also hellped but It just retuns me to the same empty form.
Can you tell me what I have to change to get it to actualy link it to the redirect link?
As I understand your question, you want to redirect users to another site after they've submitted a form.
What I have done in the past is modify the URL of the new form so that instead of the new item url being : http://mysite/org/hr/Lists/Exit/Item/newifs.aspx?List=b5b9e317%2D4366%2D4557%2D8d29%2Db5dedc71a75a&Source=http%3A%2F%2Fmysite%2Forg%2Fhr%2FLists%2FExit%2FCompleted%2Easpx&RootFolder=&Web=a86f3198%2D79a6%2D4e7f%2Daa26%2D448559533df8
I change the address after &Source in the above URL to the other site. So, it would now look like this:
http://mysite/org/hr/Lists/Exit/Item/newifs.aspx?List=b5b9e317%2D4366%2D4557%2D8d29%2Db5dedc71a75a&Source=http://www.google.com
What will happen, form will open, they'll save, and once the form closes, it will direct them to Google. I didn't need to modify the OOB save buttons - it's a good deal cleaner and quicker!
Hope this helps.

django model attribute edit & save with no extra page

I rende certain objects values in django template in a form of a table.
I let user to edit the value and save the edit so I can track the history of edit.
At the moment I use django forms to let user do single object attribute value OR chosen objects attribute values OR all of them and save it.
My problem is with forms is that the way it works at the moment is:
user clicks a value in 'main' page so it links to object 'edit' page in which I return a form so user can edit it.
The problem is with that extra url or extra page. I do not want to do it via separate pages.
I would like to click on the object (like in the excel) and change the value there in 'main' page and submit the edits from the same page.
How can I achieve it with django ?
Can somebody point me into right direction and point out what I should read about to understand it or how I should do it ?
I want to edit either single or let user edit multiple objects values and save the changes and still be able to track the history of edits / changes.
You should look into modals. So when a user clicks to edit it will display a pop-up that you can render the form in without leaving the page.

Saving an incomplete Django form

I have a rather long form that users can't always complete in one sitting. I'd like users to be able to hit a button and save the form for completion later. My first thought was to simply save the form anyway and just flag it as incomplete somehow. However, I can't seem to get around the fact that incomplete forms are invalid and can't be forced to save. For example, if a required field near the end of the form is blank the form can't be saved to the database even if I skip the form.is_valid() step.
Is there another way to save the form's data temporarily? Also, I'm aware this question has been asked before but I'm afraid this answer wasn't very helpful: Django Save Incomplete Progress on Form
Update
Thank you all for the responses so far. Some of the answers below made me realize I omitted a detail from my original question. I need to be able to let the user choose whether or not to finish a form when they return. The users enter information into this form several times a day. They may come back to the form not ready to finish form item A but instead needing to fill out form item B from the beginning. So, just auto-populating the form with their last incomplete form won't quite do the trick. I'm sorry this didn't occur to me when I posted the original question.
If you use django-merlin you can split up that long ass form into lots of smaller forms, and each previous form will be saved in the user's session just waiting for them to come back to it. If they navigate away and come back to it through the wizard's base url, they will be resumed at the same place they left off.
I was asked to implement this type of functionality for the Django form wizard. The solution I came up with (without going too deep into the details) was to save the cleaned data at every step in a json format (json.dumps(self.get_all_cleaned_data()) to a table in my database.
Later, if someone wanted to resume the form, they could retrieve the record from the database and the information could be repopulated into the form using the (initial.update) method (def get_form_initial(self, step):). Hope this helps give you an idea.

How to override/update information from POST when creating model

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.

Photologue ImageModel required field question (and how to override)

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.