Saving ModelForm progress values to session in Django - django

I have flow where users can create (model) forms. If form is valid, object gets saved and flow continues, but selection is in multiple pages. I need to keep current state of created object, which cannot be saved before it's completely valid.
One thing I can do is to always pass things around those views in the ModelForm to make sure, that user never loses data, but I also wanna make sure, that if he leaves the flow and comes back, he doesn't lose data, that he already entered previously.
That's why I decided I wanna save all the fields to session.
Is this correct approach?
How would you do this?
Where would you put this session logic?
What's best way of getting the fields from incomplete form to be saved?
Edit:
Please don't give me advice on how to use session, I am talking more about high level logic and architecture than specific implementation.
I should describe my flow a bit more. Model has 3 fields.
normal dropdown (foreign key referencing another model)
textfield
another foreign key, but this time not done by select, but it's own separate page with lots of filters to help user pick the right (foreign) model
Flow is not linear, because user can start in different parts of page.
Sometimes user can go to page, where he has first 2 fields + button "Browse", which takes you to selection page for 3rd field. Then after he selects field there, he comes back.
But sometimes he selects first this field and then comes to screen with 2 remaining fields, where he needs to fill those.

django-formtools offers a great way to do this using Form wizard.
The form wizard application splits forms across multiple Web pages. It
maintains state in one of the backends so that the full server-side
processing can be delayed until the submission of the final form.
More info here https://django-formtools.readthedocs.io/en/latest/wizard.html

to save in session:
request.session["variable_name"] = "value"
to get from session request.session["variable_name"]. sure you can use request.session.get("..") in both too

Related

Saving all user input data in Django simply?

This is may be an obvious question to a Django expert, but is there a way that I can save all user inputs (clicks through content without having to explicitly save every entry in a table). If this is possible, then how do I access it later?
If I have to create models, like this I can:
#(within a view function)
UserInputs.objects.get_or_create(user=request.user,
selection1=request.POST.get('selection1'),
id=request.POST.get('id')),
thumbs_up=request.POST.get('thumbs_up'),
thumbs_down=request.POST.get('thumbs_down'),
comments=request.POST.get('comments')
)
Is there an easier way to get it done? Because I have lots and lots of different user click inputs and specifying every one like this will really slow down my application.
Is this data by chance saved in one of the sessions tables? Or can we create a custom sessions table to do this?

Netsuite Customization of Prospect Form

I need to customize the Prospect Form in such way that the fields from subtabs like (Relationship-Contact are sitting on the main tab). We need to use this form and add fields in a sequential order. Also I need some of those fields to fill in customer form once prospect is converted. I have been using Netsuite only a few weeks but have used other systems where I could customize fields from related tables with a drag and drop functionality.Is there such a thing in Netsuite?
Thank you
Prospects and Customers are just stages of the same underlying record. Information you fill in for a prospect will still be there if the prospect converts to a customer.
As far as entry forms go the Netsuite help is not bad in this area. See https://system.na1.netsuite.com/app/help/helpcenter.nl?fid=section_N2853340.html for how to start to customize your entry forms. In particular check the section called "Moving Fields and Lists between Subtabs"
You can't control sequential data entry without a client script or possibly a workflow but the help link above will get you started on putting the fields in the logical entry order.
While in your prospect form that you want to update select 'Customize' from the top right. Then 'Customize Form'.
You'll see a button at the top called "Move elements between subtabs". Use this to move items around. After you move them you may want to go to the "Screen Fields" sub tab under the "Main" section and adjust the positioning of all the fields on your main form because when you move items between tabs they don't necessarily fall where you want them to.
As far as your fields flowing to the Customer, they will flow just fine because as someone else mentioned, a prospect record is an entity record (like customer and lead) so the record is promoted from lead to prospect then finally customer.
I agree with the other answer, get used to NetSuite help. I make a shortcut to Suite Answers, Schema Browser, SuiteScript API and SuiteScript Examples for quick reference. The NetSuite videos aren't too bad either worth looking at.
To move standard 'Lists' like Relationships, Contacts, Transactions etc this is also on the Move Entry Form Elements, look for the Lists subtab, next to Fields.

Detect which fields change in a Django ModelForm

I have an app where user submitted data needs to go through a verification process before it shows up on the site. At the moment this means they cannot edit the item without removing it from the site (so our admins can check it's okay).
I'd like to write another model where I can store revisions. Basically three fields where I store the date submitted, a boolean saying if the user is ready for that revision to be considered and a third where I store all the changes (as a pickled/JSON dict).
The problem I have at the moment is I don't want to bombard the admins with a complete listing each time. I only want them to see the changed fields. This means I need a way of generating a list of which fields have changed when the user submits the edit ModelForm so I only save this data in the revision.
There are probably several ways of doing this but my post-pub-quiz brain is slightly numb and can't think of the best way. How would you do it?
In terms of where this would go, I'd probably write it as an abstract ModelForm-inheriting class that other forms use. I'd override save() to stop it writing the data directly back to database (I'd want to redirect it through this fancy new revisions model).
Come to think of it, is there an app that already does this generically?

Assigning a "database id" to multiple html ids on a page

I will use model.id when referencing the id for the table in the database, and id when referencing the id given to elements in my html.
I have a django project where I am using some hidden form fields (all forms have the same id right now for that hidden field) to house the model.id. This works great as long as the model.id is known when the page is rendered.
I am now attempting to modify the process to work when no model.id is given (ie someone has chosen to create a new instance of my model). As far as the backend goes I have this working. No model.id supplied and the view knows it should give empty forms. At this point I choose not to create a new instance of the model, as I only want to if the user actually enters something in one of the forms.
If the user enters something in a form then the form processing creates a new instance of model and passes the id back to the users browser. What I was attempting to do is use the jquery form plugin to save the return data somewhere hidden, which I would then look at and use val to set all of the hidden fields' ids to the model.id that was returned so the next field/form the user submits will know to write to the model that was just created.
Now looking at this I'm guessing the idea of having multiple elements with the same id is bad, but I really do want them to always be the same and only have the hidden fields there to house that same Model.id on every form on the page.
I tried doing something like follows. However only one of the ids on the page actually got the value assigned. Is there a different way I should be accomplishing this goal? Is there something I should add to make all occurrences of id to be set with something like .val(model.id)? If not, does anyone have any suggestions on how to go about this? Maybe django provides a cleaner way of doing exactly what I'm trying to accomplish?
A response returned from form submission.
<response>
<the_model_id_brought_back>3732</the_model_id_brought_back>
...
<response>
The jQuery code attempting to set all of the "id_in_multiple_places" ids to the model.id returned.
jQuery('#descriptionForm').ajaxForm({
target: '#response',
success: function(data) {
the_model_id = jQuery('#response').find("the_model_id_brought_back").html();
jQuery('#id_in_multiple_places').val(the_model_id);
}
});
To explain why I have multiple forms like this. Forms consist of 1 visible field. Multiple forms are on the page. When a user leaves a field (which means they leave the form as well) I will submit that form to the server. This will allow their data to always be saved even if they stop half way through and throw their computer out a window. They can go to a different computer and pick up where they left off.
Thanks.
Now looking at this I'm guessing the idea of having multiple elements with the same id is bad
It's not only bad, it's impossible. You cannot do this. You can get around this by using classes, which don't have to be unique, but you probably shouldn't.
What you should do, is assign the elements sensible class names, and assign their common ancestor the ID. You can start at that element and traverse downwards to find the sub-elements by class name.

How to select from a large number of options when completing a form

I am building a web app that allows our field staff to create appointments. This involves creating a record that contains many foreign keys, of which some come from very large tables. For example, the staff will need to select one of potentially thousands of customers.
What's the best way of doing this in Django?
A pop-up box that allows the users to search for customers, gives them the results, the user selects the results, then fills out the main appointment form and then
disappears?
Changing the appointments form to a customer selection page that
then reloads the appointments page with the data in a hidden form? Or
holding the data in some session variables?
Some from of Ajax approach.
A wizard where the flow is: a customer search page, a list of results and they select from results, then a search page for the next option (for example product selection), etc etc
(I'd like to keep it as simple as possible. This is my first Django
project and my first web project for more years than I care to
remember)
ALJ
Imho you should consider some kind of autocomplete fields. I think this results in the best usability for the user. Unfortunately, this always involves Ajax. But if you think that all users have JS turned on this is no problem.
E.g.
django-autocomplete
or what is probably more powerful:
django-ajax-selects
If you do the wizard approach, it will take longer for the user to accomplish the task and makes it harder to change selections.
Edit:
Well with django-ajax-selects you can define how the results should look like. So you can e.g. add the address behind the name.
Quote:
Custom search channels can be written when you need to do a more complex search, check the user's permissions, format the results differently or customize the sort order of the results.
I have done this before by integrating a jQuery autocomplete plugin. But, seeing as this is your first project and your desire to keep it simple, I suppose you could go with the session data option. For instance, you could show a search page where users could search for and select a customer. You could then store the, say, ID of the selected customer object as session data, and use it to pre-populate the corresponding field in the form when displaying the form. That's what I think offhand.