Thanks Furbee, UNDERSTOOD.
Thanks again for detailled and instructive answers. Alain On 2 nov, 21:36, Furbee <furbeena...@gmail.com> wrote: > 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 <youp...@gmail.com> 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 ? 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 > > ... > > 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.