class Previsione(models.Model):
nave = models.CharField(maxlength=50)
data_manovra = models.DateField()
h_inizio = models.TimeField()
rims = models.ManyToManyField(Rim)
into the views.py I use this code to save the submitted data:
....
if req.method == 'POST':
myform = nf.models.form_for_model(Previsione)(req.POST)
if myform.is_valid():
dati = myform.save(commit=False)
if varid is not None:
dati.id=varid
dati.save()
dati.rims = req.POST.getlist('rims')
return HttpResponseRedirect('.')
else:
....
but when I update the data the old rims are deleted and the new inserted ... is
possible to UPDATE the rims data ? cioe', is possible to leave unchanged the
rims data if are the same ?
tanks in advance ...
--
#include <stdio.h>
int main(void){char c[]={10,65,110,116,111,110,105,111,32,98,97,114,98,111,110,
101,32,60,104,105,110,100,101,109,105,116,64,116,105,115,99,97,108,105,110,101,
116,46,105,116,62,10,10,0};printf("%s",c);return 0;}
> Hi all,
> I have a class with a many2many field:
...
> but when I update the data the old rims are deleted and the new inserted ... is
> possible to UPDATE the rims data ? cioe', is possible to leave unchanged the
> rims data if are the same ?
data.rims.add(req.POST.getlist('rims'))
should do what you need it to do, assuming what has been posted is a
list of valid primary keys or object instances.
data.rims is a descriptor; it behaves a lot like an attribute (because
it has __get__ and __set__ implementations), but it also has some
helpful utility methods (like add(), remove() and clear()).
Yours,
Russ Magee %-)
*****************
Exception Type: TypeError
Exception Value: list objects are unhashable
*****************
I've try with:
for newrim in req.POST.getlist('rims'):
dati.rims.add(newrim)
but the data are added also when I update the Previsione ...
searching on group archive, I think I must implement a 'save' method
into the Previsione class ... is correct ?
and if it's correct, how can I access the POST data from the save() method ?
> Yours,
> Russ Magee %-)
tanks ...
for the moment, I've resolved this way:
if req.method == 'POST':
myform = nf.models.form_for_model(Previsione)(req.POST)
if myform.is_valid():
dati = myform.save(commit=False)
salva_rims = True
list_rims = req.POST.getlist('rims')
if varid is not None:
dati.id=varid
old_rims=list(dati.rims.all())
new_rims=Rim.objects.in_bulk(list_rims).values()
old_rims.sort()
new_rims.sort()
if old_rims == new_rims:
salva_rims = False
dati.save()
if salva_rims == True:
dati.rims = list_rims
return HttpResponseRedirect('.')
else:
any better (and more elegant !! ;-)) idea ??
tanks in advance ....
Oops - sorry - missed a small, but very important bit - You need to
roll out the list as arguments. Ordinarily, the usage of add() would
be:
data.rims.add(1,3,7,9)
but since you already have a list, you use:
data.rims.add(*req.POST.getlist('rims'))
Sorry for leading you astray.
> I've try with:
>
> for newrim in req.POST.getlist('rims'):
> dati.rims.add(newrim)
This is effectively the same solution, but rolled out in code.
> but the data are added also when I update the Previsione ...
> searching on group archive, I think I must implement a 'save' method
> into the Previsione class ... is correct ?
I'm not sure I understand what you're trying to do here. The save()
method on an instance doesn't affect the m2m relations. However, there
are other mechanisms, such as saving a web form, that will modify m2m
forms.
How are you updating the Previsione instances? Using a web form?
Programmatically? Some other way?
> and if it's correct, how can I access the POST data from the save() method ?
In short, you can't. However, this doesn't stop you from adding a
different method to your model that has the side effect of calling
save.
Yours,
Russ Magee %-)
what do you mean with "saving a web form" ?? saving the form and NOT
the save method on instance ??
I use :
***
myform = nf.models.form_for_model(Previsione)(req.POST)
if myform.is_valid():
dati = myform.save(commit=False)
***
to change eventually the 'id' value for the insert/update
***
if varid is not None:
dati.id=varid
***
> How are you updating the Previsione instances? Using a web form?
> Programmatically? Some other way?
I create a web form to insert/update the Previsione data ... my urls.py:
urlpatterns = patterns('modulistica.savona.views',
(r'^index/$', 'index'),
(r'^Previsione/$', 'previsione'),
(r'^Previsione/(?P<varid>\d+)/$', 'previsione'),
)
when I get the 'Previsione/' URL I go to insert the data ... when I get
the 'Previsione/10/' URL I go to update the data of the Previsione(pk=10).
****************************
the previsione function :
def previsione(req, varid=None):
if req.method == 'POST':
myform = nf.models.form_for_model(Previsione)(req.POST)
if myform.is_valid():
dati = myform.save(commit=False)
salva_rims = True
list_rims = req.POST.getlist('rims')
if varid is not None:
dati.id=varid
clean_path=re.sub('/[0-9]+/','',req.path)
else:
clean_path = req.path
# controlla se ci sono stati cambiamenti
# nel campo m2m
#
old_rims=list(dati.rims.all())
new_rims=Rim.objects.in_bulk(list_rims).values()
old_rims.sort()
new_rims.sort()
if old_rims == new_rims:
salva_rims = False
dati.save()
if salva_rims == True:
dati.rims = list_rims
return HttpResponseRedirect(clean_path)
else:
# method GET
#
if varid is None:
myform = nf.models.form_for_model(Previsione)()
else:
instance = get_object_or_404(Previsione, pk=varid)
myform = nf.models.form_for_instance(instance)()
return render_to_response('create_form.html', \
{ 'titolo': 'Archivio Previsioni',
'form': myform.as_table() })
tanks for the help ;-))) and sorry for my english !!
Ok - this is saving a form created from a model. Since your model
contains a m2m field, the form representing that model will have an
m2m widget, and when you save() the form, the m2m relation on the
object will be modified.
However, if you had an instance of Previsione, and saved it, the m2m
fields would not be affected:
obj = Previsione(...# some initial data #...)
obj.save() # Does not modify m2m data
What was confusing me was that it sounded like you wanted to override
save() on Previsione (the model), rather than overriding save() on the
Previsione form. The former idea won't help; the latter idea will.
What you describe in your example looks to be correct - rather than
using the save() method on the form for Previsione, you are manually
saving the object modified by the form, which allows you to be
specific about saving m2m relations, etc.
If you were really fancy, you could wrap that logic into a save method
on a custom form; this would make your view a little cleaner, but
wouldn't affect the way the view operates.
Yours,
Russ Magee %-)
ok ... first of all TANKS for the help and for the very clear explanation
;-)))
I've resolved (more clear and more coincise !!) with:
*******
def previsione(req, varid=None):
if req.method == 'POST':
myform = nf.models.form_for_model(Prev)(req.POST)
if myform.is_valid():
if varid is not None:
instance = get_object_or_404(Prev, pk=varid)
newforms.models.save_instance(myform, instance)
else:
myform.save()
clean_path=re.sub('/[0-9]+/','',req.path)
return HttpResponseRedirect(clean_path)
else:
....
********
the last thing is that the m2m data are ALWAYS updated with an increment of
the 'id', even if data are unchanged ... but I think I've to "play"
(eventually ;-))) with the 'save()' method ...
tanks again .... my turn next time ... I hope ;-)))
bye ....