On Thu, Feb 7, 2013 at 1:54 PM, vijay shanker <[email protected]> wrote:
> Hi
> I am using django version 1.4.3
> I am using two signals in my models.py
> one is m2m_changed, so i can have a counter field (numcounter) of number of
> m2m fields attached, and another is post_save so i can decide whether to
> have a OneToOneField (cartrule, is to be applied only if there are more than
> 2 fields) or not.
> my models.py is:
>
> class CartItem(models.Model):
>     content_type    = models.ForeignKey(ContentType)
>     object_id       = models.PositiveIntegerField()
>     content_object  = generic.GenericForeignKey('
> content_type','object_id')
>     quantity        = models.PositiveIntegerField(default=0)
>     is_abandoned    = models.BooleanField(default=False)
>     created_at      = models.DateTimeField(auto_now_add=True)
>     update_at       = models.DateTimeField(auto_now=True)
>     def __str__(self):
>         return self.content_object.name
>
> class CartRule(models.Model):
>     ##some field
>     pass
>
> class Cart(models.Model):
>     cart_id             = models.CharField(max_length=50, null=False)
>     customer            = models.ForeignKey(Customer,null=True,blank=True)
>     cartitems           = models.ManyToManyField(CartItem,null=True)
>     created_at          = models.DateTimeField(auto_now_add=True)
>     update_at           = models.DateTimeField(auto_now=True)
>     cartrule               =
> models.OneToOneField(crapclass,null=True,blank=True)
>     num_cartitem        = models.IntegerField()
>     def __str__(self):
>         return self.cart_id
>
> @receiver(post_save, sender=Cart)
> def apply_condition(sender,instance,created,raw,using,*args,**kwargs):
>     # i want to decide here if num_cartitem is greater than 2 its ok to have
> a cartrule
>     pass
>
> @receiver(m2m_changed)
> def save_cartitem_counter(sender, instance, signal,*args, **kwargs):
>     if kwargs['action'] == 'post_add':
>         instance.num_cartitem = instance.cartitems.all().count()
>         instance.save()
>
> the issue is apply_condition gets called twice, with similar value of args,
> first with older value of m2m (cartitem) field in Cart, the other time with
> the values i intended to save
> I looked into older post but still could not figure out the whys.How should
> i go about this ?
>

When you save a Cart instance, the post_save signal is triggered.
If the M2M relationship is changed as well, then the m2m_changed
signal is triggered. Your handler for this then re-saves the Cart
instance after denormalising data, which triggers the post save signal
for a second time.
You should probably connect the M2M receiver to a specific sender too,
currently it will fire whenever any M2M on any model is changed.

Keeping denormalized data like that is a pain, could you do without
it, and re-calculate it where necessary?

Alternatively, you could use a named intermediary M2M relationship:

https://docs.djangoproject.com/en/1.4/topics/db/models/#intermediary-manytomany

and connect signals on post_create and post_delete to the intermediary
model, updating the Cart as necessary.

This is a little more logical, since you wish to denormalise the data
whenever an item is added to or removed from a cart, ie whenever a row
is added or deleted to the intermediate table. Naming the relationship
allows you to connect the signals to the right place.

Cheers

Tom

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-users?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to