views:

167

answers:

2

I've got a model called Card which has a ManyToMany relationship to Tag. When I save a Card, I'd like to create a Product as well, which I want to have the same ManyToMany relationship to tag.

How do I access the instance's tags? self.tags.all() gives an empty list, while if I check after saving, the card actually has tags. My code is below. For the record, I am using Django 1.0.5.

class Card(models.Model): 
    product     = models.ForeignKey(Product, editable=False, null=True) 
    name       = models.CharField('name', max_length=50, unique=True, help_text='A short and unique name or title of the object.') 
    identifier = models.SlugField('identifier', unique=True, help_text='A unique identifier constructed from the name of the object. Only change this if you know what it does.', db_index=True) 
    tags       = models.ManyToManyField(Tag, verbose_name='tags', db_index=True) 
    price      = models.DecimalField('price', max_digits=15, decimal_places=2, db_index=True) 
    def add_product(self): 
        product = Product( 
            name = self.name, 
            identifier = self.identifier, 
            price = self.price 
        ) 
        product.save() 
        return product 
    def save(self, *args, **kwargs): 
        # Step 1: Create product 
        if not self.id: 
            self.product = self.add_product() 
        # Step 2: Create Card 
        super(Card, self).save(*args, **kwargs) 
        # Step 3: Copy cards many to many to product 
        # How do I do this? 
        print self.tags.all() # gives an empty list?? 
A: 

You aren't adding any tags to the Card. You can't add ManyToMany relationships until after you save the Card, and there's no time between the save call and the call to self.tags.all() for them to be set.

Thomas Wouters
A: 

Are you using the django-admin to save the model and tags? The many-to-many fields don't get saved there until after the post-save signal of the model. What you can do in this case is overide the admin classes save_model method. E.g.:

class CardAdmin(admin.ModelAdmin):

    def save_model(self, request, obj, form, change):
        obj.save()
        form.save_m2m()
        #from this point on the tags are accessible
        print obj.tags.all()
dvine multimedia