django: save one field of a formset at a time - django

My django app connects to a sql server database. On my template I have an editable datatable/formset. Whenever a user edits a field and hits enter, I want only the edited field to be saved. As far as I know AJAX is the only approach to do this, especially if you want the value of the edited field to be the only one transfered to the server. Let's put this case aside for now and accept transferring all data of the formset at once.
Also, the formset is based on a sql server view that includes calculated values. Hence, executing formset.save() will raise an error. Instead I have to use the underlying table to save the modified value. What would be best practice to identify the changed field and save only this one?
Let's say the underlying table is costsperdiem that corresponds to a model in my django app and 'costs' is the name of the editable field I want to save then my approach is as follows:
check if the formset is valid
loop through the forms of the formset using changed_data to seek for the modified field
using a model instance to filter for the modified record
pass the modified value to the model
save the model
which looks like this in code:
formset = FormSet_CostsPerDiem(request.POST)
if formset.is_valid():
for f in formset.forms:
if 'costs' in f.changed_data:
val2save=f.cleaned_data['costs']
id=f.cleaned_data['id_costsperdiem']
rec2save=costsperdiem.objects.filter(pk=id)
rec2save.costs=val2save
rec2save.save()
What is best practice to do something like this?

Related

Accesing information from a POST form in django 1.6

I have a couple of forms, one is created from as a ModelForm and the other is a simple Form. Both of them are used in a request.POST, and to obtain the information from them I am using to different methods:
For the ModelForm form, I do this:
form = ApplicantForm(request.POST)
if form.is_valid():
applicant = form.save(commit=False)
applicant.confirmation_code = '999999'
applicant.save()
For the simple form, I am using:
form = ConfirmationCode(request.POST)
code = request.POST['confirmation_code']
confirmation_id=request.POST['confirmation_id']
As you can see, to access the information in the first form I am using the "form.save.ANYFIELD", and for the second one I am using "request.POST['ANYFIELD']. Is it possible to access the the information in the first form using the request.POST methods even if it hasnt been saved? Which is better?
You can try like this for modelform:
form = ApplicantForm(request.POST)
if form.is_valid():
app_code= form.cleaned_data['confirmation_code'] #assuming confirmation_code is a field in your modelform
.....
You seem a bit confused about what saving is doing in a modelform. When you call form.save(), you're creating a new instance of the model the form is associated with, and (unless you specify commit=False) saving that data to the database. Because you have an instance, you can use any of the normal model instance methods and access patterns.
If you want to use a form without an associated model, you can't call save - because there's nothing to save, and no model to create an instance of - but you should access the data via the form.cleaned_data dictionary after you call form.is_valid(). This is because the data in cleaned_data has been validated according to the rules in the form, and converted into the relevant types where necessary: for instance, if you had an IntegerField in your form called my_number, request.POST['my_number'] will be a string like "3" but form.cleaned_data['my_number'] will be an actual integer, 3.

Django request.GET to display value of form field

Is there a way that i can access the values in my form fields before submitting the form.
I need to store the value of one of my fields in request.session[] so as to access it later ( in the same view). I tried doing it using request.GET but it always none.
request.GET.get('name')
where name is the field in a model.
Update
I want to store the value of the form field which is random value generated every time the form is displayed. My models.py contains a random() method which is the default value of the field.
I want to store the field value in sessions, so that i can get the same field value after i return to the page after navigating a few more pages from that page
This is what i was doing:
Django request.session does not resolve
First of all careful when using random in models:
Random/non-constant default value for model field?
Once this is clear I suppose you initialise the form in the view, is there that you need to access the form and get the value for put it in session.
For example
form = MyModelForm();
request.session['your_session_key'] = form.data['field_name']
As far as I understand in some cases you want to set this value in the form from the session instead, for do that you can use the initial data as described here.
https://docs.djangoproject.com/en/dev/ref/forms/api/#dynamic-initial-values
Hope this helps

Django ManyToMany Field in form - unnecessary database calls?

In a django form that has a manyToMany field - is there a database call to retrieve each object in the list when you're adding a new entry? Is this necessary/ wasteful?
For example:
class MyForm(ModelForm):
likes = forms.ModelMultipleChoiceField(queryset=Videos.objects.all())
....
the form is submitted with a list of project id's. within the clean() method likes becomes a list of Video objects. However you can do:
self.instance.likes.add() ...without ever having to get the objects.
...
is it wasteful that the objects are being retrieved first before updating the relationship? if not, why?
I would say that every time you save the form, it would be evaluating the queryset you passed it to check that each ID is within that queryset. if you wish to optimize the behavior, try subclassing ModelMultipleChoiceField and removing the checks/making them more streamlined.

django inlineformset_factory, view changed fields on save

I am creating some custom validation, that on save checks if certain fields values have changed.
On POST, is there a way in the view that I can check what fields have changed for that formset?
I am currently looping through the formset and am able to view individual field values, so I could compare them to a query. It just seems to be a bit more than necessary considering the formset doesn't go through the save process if nothing has changed.
Any help is appreciated.
Add a method to your formset:
def has_changed()
return all([form.has_changed() for form in self.forms])
Similarly, the form also documents the changed_fields, which you can concatenate in your formset.
I don't think formset.save() blindly overwrites all entries into the db. It checks the changed forms, which I think is available in formset.changed_forms and it updates only those rows in the db.

django forms overwrite data when saved

If a have a form, with the data from a user, let's say a CV, and i save the data from the form into a database, but i don't want that a CV from the same user to be stored in the database more than once(when edited form instance)
I want it to be overwritten every time it is saved by one same user.
How can i do it?
thanks a lot
Django's save() should handle this for you automatically.
To give an example, you'll usually submit a form in a way something like this:
...
form = UserCVForm(request.POST, instance=user_cv)
if form.is_valid():
form.save()
...
'instance=user_cv' tells django that you want to update an existing entry - specifically 'user_cv'. Without 'instance=user_cv', Django will insert a new entry into the database.
So in short, see if a user_cv exists already with something like user_cv = UserCV.objects.get(user=user_id). If a user_cv exists, be sure to whack an instance=user_cv in when populating the form.