Re: Formwizard - Many2Many field - instance needs to have a primary key value before a many-to-many relationship can be used

2011-11-02 Thread youpsla
Thanks Furbee,

UNDERSTOOD.

Thanks again for detailled and instructive answers.

Alain

On 2 nov, 21:36, Furbee  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  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

2011-11-02 Thread Furbee
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):
> > > 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

2011-11-02 Thread youpsla
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 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

2011-11-02 Thread Furbee
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 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

2011-11-02 Thread youpsla
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 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

2011-11-02 Thread youpsla
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, 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 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

2011-11-02 Thread Furbee
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
> 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

2011-11-02 Thread youpsla
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.