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 ? huuuuu Thanks again Alain On 2 nov, 20:11, Furbee <furbeena...@gmail.com> 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 <num_categories>+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 <youp...@gmail.com> 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 <furbeena...@gmail.com> 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 specific forms and field/values for > > categories. > > > > Furbeenator > > > > On Wed, Nov 2, 2011 at 10:28 AM, youpsla <youp...@gmail.com> 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 > > > > 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 > > ... > > plus de détails » -- 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.