wagtailwagtail-snippet

Wagtail adding ParentalManyToManyField relationship on save()


I'm trying to add a ParentalManyToManyField relationship on save() and when I print it looks good but it doesn't seem to save for some reason.

Example code:

# Models
class BlogProduct(models.Model):
    product_id = models.CharField(max_length=10, blank=False, null=False)

class ProductBlogPage(BlogDetailPage):
    products = ParentalManyToManyField('blog.BlogProduct', blank=True)

    product_details = StreamField(COMMON_BLOCKS + [
        ('product_name', blocks.ProductNameBlock()),
    ],
        null=True, 
        blank=True,
        use_json_field=True,
    )

    def save(self, *args, **kwargs):
        if kwargs.get('update_fields'):
            for product in self.product_details.raw_data:
                blog_product, _ = BlogProduct.objects.get_or_create(product_id='test1')
                    
                    # This is where I'm having trouble to connect product and snippets
                    self.products.add(blog_product)
                    self.save()

            print(self.products.all())
            # This prints out the querySet
            # <QuerySet [<BlogProduct: TestOne>, <BlogProduct: TestTwo>]>

    return super().save(*args, **kwargs)

Solution

  • Your call to return super().save isn't part of your save method, it's getting called during initialisation instead. It just needs indenting:

        def save(self, *args, **kwargs):
            if kwargs.get('update_fields'):
                for product in self.product_details.raw_data:
                    blog_product, _ = BlogProduct.objects.get_or_create(product_id='test1')
                    
                    # This is where I'm having trouble to connect product and snippets
                    self.products.add(blog_product)
                    self.save()
    
                print(self.products.all())
                # This prints out the querySet
                # <QuerySet [<BlogProduct: TestOne>, <BlogProduct: TestTwo>]>
    
            return super().save(*args, **kwargs)
    

    You're also calling save() during each for loop, is this what you intended?

    self.products.all() is only looking at the instance in memory, it's not looking at what's saved, which is why your queryset looks ok.

    To be honest though, I can't see what you're trying to achieve here. Your product model is just an ID field. You're wanting to be able to add new product ID's directly from the blog page editing interface?