Re: Formwizard - Many2Many field - instance needs to have a primary key value before a many-to-many relationship can be used
Thanks Furbee, UNDERSTOOD. Thanks again for detailled and instructive answers. Alain On 2 nov, 21:36, Furbeewrote: > Hi Alain, > > Sort of. With this code: > if field == 'category': > instance.save() > a Customer with 50 categories would write to the database 51 times (1 > INSERT, and 50 UPDATES). > > Including the "instance.id == None" like this: > if field == 'category' and instance.id == None: > instance.save() > will make it write to the database one or two times maximum. If the > Customer has 0 categories, it will write once (INSERT at bottom of > program). If the Customer has n categories, it will only write once > (INSERT) in the loops, and write once (UPDATE) at the bottom of the program. > > That is why it is much quicker running it this way. > > Cheers, > > Furbeenator > > > > > > > > On Wed, Nov 2, 2011 at 1:00 PM, youpsla wrote: > > Hi again > > thanks for explanations. > > > I've understood difference between Null and None. > > > I've modify the code to add "instance.id == Non" and it seems to be > > faster. > > > To be sure. You mean that if a customer has 1 category, there will be > > 2 database access (one for all informations except category and one > > for category). > > > If a customer has 50 categories, then it's 51 database access ? hu > > > Thanks again > > > Alain > > > On 2 nov, 20:11, Furbee wrote: > > > Hi Alain, > > > > Glad that it worked out! :-) > > > > To clarify, a blank is different from a Null, or "None" in > > Python/Django. A > > > blank character field is "" where a null character field is NULL. If a > > > field does not specify null=True, and you try to save an instance of that > > > object without specifying that field, it will raise a Database error. So, > > > in your loop if you hit category first, before any other fields, it would > > > try to save the instance of the Customer without specifying all of the > > > fields needed. That is why category must come AFTER all other fields that > > > are required (not null=True). > > > > You are correct. The instance = Customer() creates a new customer object, > > > when you executed instance.save() the instance information is saved > > > (INSERT) to the database, and it received a PK (id). Every subsequent > > > instance.save() actually runs (UPDATE) on the database, updating all > > fields > > > in the instance. If you have a whole lot of fields in the Customer, one > > > optimization would be to add logic to the loop that if the field is > > > 'category' and the instance has not yet been saved, save it. This way it > > is > > > only saved once before adding category and once at the end of setting all > > > attributes. This will probably be a better solution, and will hit the > > > database only twice instead of +1 times: > > > > class InscriptionWizard(SessionWizardView): > > > def done(self, form_list, **kwargs): > > > instance = Customer() > > > for form in form_list: > > > for field, value in form.cleaned_data.iteritems(): > > > if field == 'category' and instance.id == None: # if > > this > > > is a category, and the instance has not yet been saved, save it so it has > > > an id. > > > instance.save() > > > setattr(instance, field, value) > > > instance.save() > > > > Happy coding! > > > > Furbeenator > > > > On Wed, Nov 2, 2011 at 12:00 PM, youpsla wrote: > > > > Oupsss, another question in the step by step: > > > > > 1 class InscriptionWizard(SessionWizardView): > > > > 2 def done(self, form_list, **kwargs): > > > > 3 instance = Customer() > > > > 4 for form in form_list: > > > > 5 for field, value in form.cleaned_data.iteritems(): > > > > 6 if field == 'category': > > > > 7 instance.save() > > > > 8 setattr(instance, field, value) > > > > 9 instance.save() > > > > > Line 7 : Will save in the DB all fields that have been already > > > > iterated. Then I suppose the instance.save() will not clear > > > > informations affected by the setattr() otherwise the PK is lost ... > > > > and the Line 9 doesn't know wich PK to use > > > > > Then I suppose the Line 9 will save all informations of the form, > > > > those which have been already saved by Line 7 and add category. Then I > > > > suppose Django will perform an "UPDATE" rather than an "INSERT" SQL > > > > statement ? > > > > > Is it right ? > > > > > Again, regards for the time spend to answer. > > > > > Alain > > > > > On 2 nov, 19:03, Furbee wrote: > > > > > In your Customer model there are fields which cannot be Null, so you > > > > cannot > > > > > instance.save() before setting those properties. So, you may have to > > > > check > > > > > for the category field in your loop and if it is category, save the > > > > > instance first. Something
Re: Formwizard - Many2Many field - instance needs to have a primary key value before a many-to-many relationship can be used
Hi Alain, Sort of. With this code: if field == 'category': instance.save() a Customer with 50 categories would write to the database 51 times (1 INSERT, and 50 UPDATES). Including the "instance.id == None" like this: if field == 'category' and instance.id == None: instance.save() will make it write to the database one or two times maximum. If the Customer has 0 categories, it will write once (INSERT at bottom of program). If the Customer has n categories, it will only write once (INSERT) in the loops, and write once (UPDATE) at the bottom of the program. That is why it is much quicker running it this way. Cheers, Furbeenator On Wed, Nov 2, 2011 at 1:00 PM, youpslawrote: > Hi again > thanks for explanations. > > I've understood difference between Null and None. > > I've modify the code to add "instance.id == Non" and it seems to be > faster. > > To be sure. You mean that if a customer has 1 category, there will be > 2 database access (one for all informations except category and one > for category). > > If a customer has 50 categories, then it's 51 database access ? hu > > > Thanks again > > Alain > > > > On 2 nov, 20:11, Furbee wrote: > > Hi Alain, > > > > Glad that it worked out! :-) > > > > To clarify, a blank is different from a Null, or "None" in > Python/Django. A > > blank character field is "" where a null character field is NULL. If a > > field does not specify null=True, and you try to save an instance of that > > object without specifying that field, it will raise a Database error. So, > > in your loop if you hit category first, before any other fields, it would > > try to save the instance of the Customer without specifying all of the > > fields needed. That is why category must come AFTER all other fields that > > are required (not null=True). > > > > You are correct. The instance = Customer() creates a new customer object, > > when you executed instance.save() the instance information is saved > > (INSERT) to the database, and it received a PK (id). Every subsequent > > instance.save() actually runs (UPDATE) on the database, updating all > fields > > in the instance. If you have a whole lot of fields in the Customer, one > > optimization would be to add logic to the loop that if the field is > > 'category' and the instance has not yet been saved, save it. This way it > is > > only saved once before adding category and once at the end of setting all > > attributes. This will probably be a better solution, and will hit the > > database only twice instead of +1 times: > > > > class InscriptionWizard(SessionWizardView): > > def done(self, form_list, **kwargs): > > instance = Customer() > > for form in form_list: > > for field, value in form.cleaned_data.iteritems(): > > if field == 'category' and instance.id == None: # if > this > > is a category, and the instance has not yet been saved, save it so it has > > an id. > > instance.save() > > setattr(instance, field, value) > > instance.save() > > > > Happy coding! > > > > Furbeenator > > > > > > > > > > > > > > > > On Wed, Nov 2, 2011 at 12:00 PM, youpsla wrote: > > > Oupsss, another question in the step by step: > > > > > 1 class InscriptionWizard(SessionWizardView): > > > 2def done(self, form_list, **kwargs): > > > 3instance = Customer() > > > 4for form in form_list: > > > 5for field, value in form.cleaned_data.iteritems(): > > > 6if field == 'category': > > > 7instance.save() > > > 8setattr(instance, field, value) > > > 9instance.save() > > > > > Line 7 : Will save in the DB all fields that have been already > > > iterated. Then I suppose the instance.save() will not clear > > > informations affected by the setattr() otherwise the PK is lost ... > > > and the Line 9 doesn't know wich PK to use > > > > > Then I suppose the Line 9 will save all informations of the form, > > > those which have been already saved by Line 7 and add category. Then I > > > suppose Django will perform an "UPDATE" rather than an "INSERT" SQL > > > statement ? > > > > > Is it right ? > > > > > Again, regards for the time spend to answer. > > > > > Alain > > > > > On 2 nov, 19:03, Furbee wrote: > > > > In your Customer model there are fields which cannot be Null, so you > > > cannot > > > > instance.save() before setting those properties. So, you may have to > > > check > > > > for the category field in your loop and if it is category, save the > > > > instance first. Something like the following: > > > > > > views.py (in clients application) > > > > - > > > > class InscriptionWizard(SessionWizardView): > > > >def done(self, form_list, **kwargs): > > > >instance = Customer() > > > >for form in
Re: Formwizard - Many2Many field - instance needs to have a primary key value before a many-to-many relationship can be used
Hi again thanks for explanations. I've understood difference between Null and None. I've modify the code to add "instance.id == Non" and it seems to be faster. To be sure. You mean that if a customer has 1 category, there will be 2 database access (one for all informations except category and one for category). If a customer has 50 categories, then it's 51 database access ? hu Thanks again Alain On 2 nov, 20:11, Furbeewrote: > Hi Alain, > > Glad that it worked out! :-) > > To clarify, a blank is different from a Null, or "None" in Python/Django. A > blank character field is "" where a null character field is NULL. If a > field does not specify null=True, and you try to save an instance of that > object without specifying that field, it will raise a Database error. So, > in your loop if you hit category first, before any other fields, it would > try to save the instance of the Customer without specifying all of the > fields needed. That is why category must come AFTER all other fields that > are required (not null=True). > > You are correct. The instance = Customer() creates a new customer object, > when you executed instance.save() the instance information is saved > (INSERT) to the database, and it received a PK (id). Every subsequent > instance.save() actually runs (UPDATE) on the database, updating all fields > in the instance. If you have a whole lot of fields in the Customer, one > optimization would be to add logic to the loop that if the field is > 'category' and the instance has not yet been saved, save it. This way it is > only saved once before adding category and once at the end of setting all > attributes. This will probably be a better solution, and will hit the > database only twice instead of +1 times: > > class InscriptionWizard(SessionWizardView): > def done(self, form_list, **kwargs): > instance = Customer() > for form in form_list: > for field, value in form.cleaned_data.iteritems(): > if field == 'category' and instance.id == None: # if this > is a category, and the instance has not yet been saved, save it so it has > an id. > instance.save() > setattr(instance, field, value) > instance.save() > > Happy coding! > > Furbeenator > > > > > > > > On Wed, Nov 2, 2011 at 12:00 PM, youpsla wrote: > > Oupsss, another question in the step by step: > > > 1 class InscriptionWizard(SessionWizardView): > > 2 def done(self, form_list, **kwargs): > > 3 instance = Customer() > > 4 for form in form_list: > > 5 for field, value in form.cleaned_data.iteritems(): > > 6 if field == 'category': > > 7 instance.save() > > 8 setattr(instance, field, value) > > 9 instance.save() > > > Line 7 : Will save in the DB all fields that have been already > > iterated. Then I suppose the instance.save() will not clear > > informations affected by the setattr() otherwise the PK is lost ... > > and the Line 9 doesn't know wich PK to use > > > Then I suppose the Line 9 will save all informations of the form, > > those which have been already saved by Line 7 and add category. Then I > > suppose Django will perform an "UPDATE" rather than an "INSERT" SQL > > statement ? > > > Is it right ? > > > Again, regards for the time spend to answer. > > > Alain > > > On 2 nov, 19:03, Furbee wrote: > > > In your Customer model there are fields which cannot be Null, so you > > cannot > > > instance.save() before setting those properties. So, you may have to > > check > > > for the category field in your loop and if it is category, save the > > > instance first. Something like the following: > > > > views.py (in clients application) > > > - > > > class InscriptionWizard(SessionWizardView): > > > def done(self, form_list, **kwargs): > > > instance = Customer() > > > for form in form_list: > > > for field, value in form.cleaned_data.iteritems(): > > > if field == 'category': > > > instance.save() > > > setattr(instance, field, value) > > > instance.save() > > > - > > > > This would of course depend on your ordering of the fields. In other > > words, > > > category would have to be the first Allow Null field in your model, > > because > > > you cannot save() until all Not Null fields have a value. If you cannot > > > order these fields so the category is last, you may have to do something > > > like: > > > > views.py (in clients application) > > > - > > > class InscriptionWizard(SessionWizardView): > > > def done(self, form_list, **kwargs): > > > instance = Customer() > > > for form in form_list: > > > for field, value in
Re: Formwizard - Many2Many field - instance needs to have a primary key value before a many-to-many relationship can be used
Hi Alain, Glad that it worked out! :-) To clarify, a blank is different from a Null, or "None" in Python/Django. A blank character field is "" where a null character field is NULL. If a field does not specify null=True, and you try to save an instance of that object without specifying that field, it will raise a Database error. So, in your loop if you hit category first, before any other fields, it would try to save the instance of the Customer without specifying all of the fields needed. That is why category must come AFTER all other fields that are required (not null=True). You are correct. The instance = Customer() creates a new customer object, when you executed instance.save() the instance information is saved (INSERT) to the database, and it received a PK (id). Every subsequent instance.save() actually runs (UPDATE) on the database, updating all fields in the instance. If you have a whole lot of fields in the Customer, one optimization would be to add logic to the loop that if the field is 'category' and the instance has not yet been saved, save it. This way it is only saved once before adding category and once at the end of setting all attributes. This will probably be a better solution, and will hit the database only twice instead of +1 times: class InscriptionWizard(SessionWizardView): def done(self, form_list, **kwargs): instance = Customer() for form in form_list: for field, value in form.cleaned_data.iteritems(): if field == 'category' and instance.id == None: # if this is a category, and the instance has not yet been saved, save it so it has an id. instance.save() setattr(instance, field, value) instance.save() Happy coding! Furbeenator On Wed, Nov 2, 2011 at 12:00 PM, youpslawrote: > Oupsss, another question in the step by step: > > 1 class InscriptionWizard(SessionWizardView): > 2def done(self, form_list, **kwargs): > 3instance = Customer() > 4for form in form_list: > 5for field, value in form.cleaned_data.iteritems(): > 6if field == 'category': > 7instance.save() > 8setattr(instance, field, value) > 9instance.save() > > Line 7 : Will save in the DB all fields that have been already > iterated. Then I suppose the instance.save() will not clear > informations affected by the setattr() otherwise the PK is lost ... > and the Line 9 doesn't know wich PK to use > > Then I suppose the Line 9 will save all informations of the form, > those which have been already saved by Line 7 and add category. Then I > suppose Django will perform an "UPDATE" rather than an "INSERT" SQL > statement ? > > Is it right ? > > > Again, regards for the time spend to answer. > > Alain > > On 2 nov, 19:03, Furbee wrote: > > In your Customer model there are fields which cannot be Null, so you > cannot > > instance.save() before setting those properties. So, you may have to > check > > for the category field in your loop and if it is category, save the > > instance first. Something like the following: > > > > views.py (in clients application) > > - > > class InscriptionWizard(SessionWizardView): > >def done(self, form_list, **kwargs): > >instance = Customer() > >for form in form_list: > >for field, value in form.cleaned_data.iteritems(): > >if field == 'category': > >instance.save() > >setattr(instance, field, value) > >instance.save() > > - > > > > This would of course depend on your ordering of the fields. In other > words, > > category would have to be the first Allow Null field in your model, > because > > you cannot save() until all Not Null fields have a value. If you cannot > > order these fields so the category is last, you may have to do something > > like: > > > > views.py (in clients application) > > - > > class InscriptionWizard(SessionWizardView): > >def done(self, form_list, **kwargs): > >instance = Customer() > >for form in form_list: > >for field, value in form.cleaned_data.iteritems(): > >if field != 'category': > >setattr(instance, field, value) > >instance.save() > >for form in form_list: > >for field, value in form.cleaned_data.iteritems(): > >if field == 'category': > >setattr(instance, field, value) > > - > > > > I'm sure there is a MUCH more elegant way of getting just the categories > > from the forms and field/value pairs, this is brute force (not very > > scalable for large number of fields), but should work. Anybody else > please, > > show code that could get the
Re: Formwizard - Many2Many field - instance needs to have a primary key value before a many-to-many relationship can be used
Oupsss, another question in the step by step: 1 class InscriptionWizard(SessionWizardView): 2 def done(self, form_list, **kwargs): 3 instance = Customer() 4 for form in form_list: 5 for field, value in form.cleaned_data.iteritems(): 6 if field == 'category': 7 instance.save() 8 setattr(instance, field, value) 9 instance.save() Line 7 : Will save in the DB all fields that have been already iterated. Then I suppose the instance.save() will not clear informations affected by the setattr() otherwise the PK is lost ... and the Line 9 doesn't know wich PK to use Then I suppose the Line 9 will save all informations of the form, those which have been already saved by Line 7 and add category. Then I suppose Django will perform an "UPDATE" rather than an "INSERT" SQL statement ? Is it right ? Again, regards for the time spend to answer. Alain On 2 nov, 19:03, Furbeewrote: > In your Customer model there are fields which cannot be Null, so you cannot > instance.save() before setting those properties. So, you may have to check > for the category field in your loop and if it is category, save the > instance first. Something like the following: > > views.py (in clients application) > - > class InscriptionWizard(SessionWizardView): > def done(self, form_list, **kwargs): > instance = Customer() > for form in form_list: > for field, value in form.cleaned_data.iteritems(): > if field == 'category': > instance.save() > setattr(instance, field, value) > instance.save() > - > > This would of course depend on your ordering of the fields. In other words, > category would have to be the first Allow Null field in your model, because > you cannot save() until all Not Null fields have a value. If you cannot > order these fields so the category is last, you may have to do something > like: > > views.py (in clients application) > - > class InscriptionWizard(SessionWizardView): > def done(self, form_list, **kwargs): > instance = Customer() > for form in form_list: > for field, value in form.cleaned_data.iteritems(): > if field != 'category': > setattr(instance, field, value) > instance.save() > for form in form_list: > for field, value in form.cleaned_data.iteritems(): > if field == 'category': > setattr(instance, field, value) > - > > I'm sure there is a MUCH more elegant way of getting just the categories > from the forms and field/value pairs, this is brute force (not very > scalable for large number of fields), but should work. Anybody else please, > show code that could get the specific forms and field/values for categories. > > Furbeenator > > > > > > > > On Wed, Nov 2, 2011 at 10:28 AM, youpsla wrote: > > Hello, > > i'm currently doning a website where user can register (without > > password, without auth module of Django). They put some informations > > and at the end (Step5Form) do multiple choices by clicking on > > checkboxes. When I click on validate on the last step I've "instance > > needs to have a primary key value before a many-to-many relationship > > can be used" error. I've search the web to find a solution but . :- > > ( > > > Here is my code: > > > models.py for Customer (in clients application) > > - > > class Customer (models.Model): > > > email_adresse = models.EmailField(max_length=255, unique=True) > > some fields . for Step2 to Step4 of the form > > category = models.ManyToManyField(Categories) > > - > > > models.py for categories (in categories application) > > - > > class Categories (models.Model): > > category = models.CharField(max_length=200) > > > def __unicode__(self): > > return unicode(self.category) > > - > > > The ManyToMany field has created(syncdb) a table > > clients_customer_category with the following columns: > > 1 id int(11) > > AUTO_INCREMENT > > 2 customer_id int(11) > > 3 categories_id int(11) > > > urls.py > > - > > urlpatterns = patterns('', > > (r'^clients/$', InscriptionWizard.as_view([Step1Form, Step2Form, > > Step3Form, Step4Form, Step5Form])), > > ) > > - > > > forms.py (in clients application) > > - > > from django import forms > > from clients.models import Customer
Re: Formwizard - Many2Many field - instance needs to have a primary key value before a many-to-many relationship can be used
Hi Furbeenator, thanks a lots, it works !!! :-))) I've use your first solution. You say that "category would have to be the first Allow Null field in your model" wich is not the case here. A "phone" field is the first step (Step0) can be empty : telephone = models.CharField(max_length=14, blank=True) Maybe I do a confusion between "Allow Null" and "blank=True) ? To be sure to understand your solution, I go bellow step by step: 1 class InscriptionWizard(SessionWizardView): 2 def done(self, form_list, **kwargs): 3 instance = Customer() 4 for form in form_list: 5 for field, value in form.cleaned_data.iteritems(): 6 if field == 'category': 7 instance.save() 8 setattr(instance, field, value) 9 instance.save() Line 5 : Iterate over field and values Line 6 : If field name is category, then save the instance BEFORE setting attribute (setattr) for the category field. Then a PK is available in the DB for saving the m2m field category, wich is done Line 9. Is it the way it works and has to works ? Again, thanks a lots for help Yahoo !!! Regards Alain On 2 nov, 19:03, Furbeewrote: > In your Customer model there are fields which cannot be Null, so you cannot > instance.save() before setting those properties. So, you may have to check > for the category field in your loop and if it is category, save the > instance first. Something like the following: > > views.py (in clients application) > - > class InscriptionWizard(SessionWizardView): > def done(self, form_list, **kwargs): > instance = Customer() > for form in form_list: > for field, value in form.cleaned_data.iteritems(): > if field == 'category': > instance.save() > setattr(instance, field, value) > instance.save() > - > > This would of course depend on your ordering of the fields. In other words, > category would have to be the first Allow Null field in your model, because > you cannot save() until all Not Null fields have a value. If you cannot > order these fields so the category is last, you may have to do something > like: > > views.py (in clients application) > - > class InscriptionWizard(SessionWizardView): > def done(self, form_list, **kwargs): > instance = Customer() > for form in form_list: > for field, value in form.cleaned_data.iteritems(): > if field != 'category': > setattr(instance, field, value) > instance.save() > for form in form_list: > for field, value in form.cleaned_data.iteritems(): > if field == 'category': > setattr(instance, field, value) > - > > I'm sure there is a MUCH more elegant way of getting just the categories > from the forms and field/value pairs, this is brute force (not very > scalable for large number of fields), but should work. Anybody else please, > show code that could get the specific forms and field/values for categories. > > Furbeenator > > > > > > > > On Wed, Nov 2, 2011 at 10:28 AM, youpsla wrote: > > Hello, > > i'm currently doning a website where user can register (without > > password, without auth module of Django). They put some informations > > and at the end (Step5Form) do multiple choices by clicking on > > checkboxes. When I click on validate on the last step I've "instance > > needs to have a primary key value before a many-to-many relationship > > can be used" error. I've search the web to find a solution but . :- > > ( > > > Here is my code: > > > models.py for Customer (in clients application) > > - > > class Customer (models.Model): > > > email_adresse = models.EmailField(max_length=255, unique=True) > > some fields . for Step2 to Step4 of the form > > category = models.ManyToManyField(Categories) > > - > > > models.py for categories (in categories application) > > - > > class Categories (models.Model): > > category = models.CharField(max_length=200) > > > def __unicode__(self): > > return unicode(self.category) > > - > > > The ManyToMany field has created(syncdb) a table > > clients_customer_category with the following columns: > > 1 id int(11) > > AUTO_INCREMENT > > 2 customer_id int(11) > > 3 categories_id int(11) > > > urls.py > > - > > urlpatterns = patterns('', > > (r'^clients/$', InscriptionWizard.as_view([Step1Form, Step2Form, > > Step3Form, Step4Form,
Re: Formwizard - Many2Many field - instance needs to have a primary key value before a many-to-many relationship can be used
In your Customer model there are fields which cannot be Null, so you cannot instance.save() before setting those properties. So, you may have to check for the category field in your loop and if it is category, save the instance first. Something like the following: views.py (in clients application) - class InscriptionWizard(SessionWizardView): def done(self, form_list, **kwargs): instance = Customer() for form in form_list: for field, value in form.cleaned_data.iteritems(): if field == 'category': instance.save() setattr(instance, field, value) instance.save() - This would of course depend on your ordering of the fields. In other words, category would have to be the first Allow Null field in your model, because you cannot save() until all Not Null fields have a value. If you cannot order these fields so the category is last, you may have to do something like: views.py (in clients application) - class InscriptionWizard(SessionWizardView): def done(self, form_list, **kwargs): instance = Customer() for form in form_list: for field, value in form.cleaned_data.iteritems(): if field != 'category': setattr(instance, field, value) instance.save() for form in form_list: for field, value in form.cleaned_data.iteritems(): if field == 'category': setattr(instance, field, value) - I'm sure there is a MUCH more elegant way of getting just the categories from the forms and field/value pairs, this is brute force (not very scalable for large number of fields), but should work. Anybody else please, show code that could get the specific forms and field/values for categories. Furbeenator On Wed, Nov 2, 2011 at 10:28 AM, youpslawrote: > Hello, > i'm currently doning a website where user can register (without > password, without auth module of Django). They put some informations > and at the end (Step5Form) do multiple choices by clicking on > checkboxes. When I click on validate on the last step I've "instance > needs to have a primary key value before a many-to-many relationship > can be used" error. I've search the web to find a solution but . :- > ( > > Here is my code: > > models.py for Customer (in clients application) > - > class Customer (models.Model): > >email_adresse = models.EmailField(max_length=255, unique=True) >some fields . for Step2 to Step4 of the form >category = models.ManyToManyField(Categories) > - > > models.py for categories (in categories application) > - > class Categories (models.Model): >category = models.CharField(max_length=200) > >def __unicode__(self): >return unicode(self.category) > - > > The ManyToMany field has created(syncdb) a table > clients_customer_category with the following columns: >1 id int(11) > AUTO_INCREMENT >2 customer_id int(11) >3 categories_id int(11) > > > urls.py > - > urlpatterns = patterns('', >(r'^clients/$', InscriptionWizard.as_view([Step1Form, Step2Form, > Step3Form, Step4Form, Step5Form])), > ) > - > > > forms.py (in clients application) > - > from django import forms > from clients.models import Customer > from categories.models import Categories > > class Step1Form(forms.Form): >email_adresse = forms.EmailField(max_length=255) > > class Step5Form(forms.Form): >category = > forms.ModelMultipleChoiceField(queryset=Categories.objects.all(), > widget=forms.CheckboxSelectMultiple, required=True) > > > views.py (in clients application) > - > class InscriptionWizard(SessionWizardView): >def done(self, form_list, **kwargs): >instance = Customer() >for form in form_list: >for field, value in form.cleaned_data.iteritems(): >setattr(instance, field, value) >instance.save() > - > > I got the following error: > - > Request Method: POST > Request URL:http://127.0.0.1:8010/clients/ > Django Version: 1.3.1 > Exception Type: ValueError > Exception Value: > 'Customer' instance needs to have a primary key value before a many-to- > many relationship can be used. > ... > ... > ▶ Local vars > C:\dev\Flash\clients\views.py in done >
Formwizard - Many2Many field - instance needs to have a primary key value before a many-to-many relationship can be used
Hello, i'm currently doning a website where user can register (without password, without auth module of Django). They put some informations and at the end (Step5Form) do multiple choices by clicking on checkboxes. When I click on validate on the last step I've "instance needs to have a primary key value before a many-to-many relationship can be used" error. I've search the web to find a solution but . :- ( Here is my code: models.py for Customer (in clients application) - class Customer (models.Model): email_adresse = models.EmailField(max_length=255, unique=True) some fields . for Step2 to Step4 of the form category = models.ManyToManyField(Categories) - models.py for categories (in categories application) - class Categories (models.Model): category = models.CharField(max_length=200) def __unicode__(self): return unicode(self.category) - The ManyToMany field has created(syncdb) a table clients_customer_category with the following columns: 1 id int(11) AUTO_INCREMENT 2 customer_id int(11) 3 categories_id int(11) urls.py - urlpatterns = patterns('', (r'^clients/$', InscriptionWizard.as_view([Step1Form, Step2Form, Step3Form, Step4Form, Step5Form])), ) - forms.py (in clients application) - from django import forms from clients.models import Customer from categories.models import Categories class Step1Form(forms.Form): email_adresse = forms.EmailField(max_length=255) class Step5Form(forms.Form): category = forms.ModelMultipleChoiceField(queryset=Categories.objects.all(), widget=forms.CheckboxSelectMultiple, required=True) views.py (in clients application) - class InscriptionWizard(SessionWizardView): def done(self, form_list, **kwargs): instance = Customer() for form in form_list: for field, value in form.cleaned_data.iteritems(): setattr(instance, field, value) instance.save() - I got the following error: - Request Method: POST Request URL:http://127.0.0.1:8010/clients/ Django Version: 1.3.1 Exception Type: ValueError Exception Value: 'Customer' instance needs to have a primary key value before a many-to- many relationship can be used. ... ... ▶ Local vars C:\dev\Flash\clients\views.py in done setattr(instance, field, value) ... - What I've tried: 1)I've search the web and didn't find any way to solve this. I've read on save_m2m() wich doesn't apply here as far I understand because no "commit=False" and this form is not a ModelForm. 2)I've trie to save in 2 steps with the hope an id has been set in the DB: -First step : for form in form_list[0:3]: .. instance.save() -Second step : for form in form_list[4]: for field, value in form.cleaned_data.iteritems(): instance.category.add(value) I've the following error : 'BoundField' object has no attribute 'cleaned_data' for the line "for field, value in form.cleaned_data.iteritems():" in Second step. Then I can maybe split my form in 2 forms, one from Step0 to Step3 and another one for Step4 and passing the id_customer in teh session but maybe there is a solution to solve this issue in one form. Help will be really appreciated. I apologize if my explanations are not enough clear (and for my english) and feel free to ask informations. Regards Alain -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.