Reputation: 3075
I'm following this guide and I get the following error when saving...
RuntimeError at /admin/products/product/2/
maximum recursion depth exceeded
Why do I get this error? I have included the full model below.
Thanks
models.py:
class Product(models.Model):
title = models.CharField(max_length=60)
qr_url = models.URLField(blank=True)
qr_image = models.ImageField(
upload_to="public/uploads/",
height_field="qr_image_height",
width_field="qr_image_width",
null=True,
blank=True,
editable=False
)
qr_image_height = models.PositiveIntegerField(null=True, blank=True, editable=False)
qr_image_width = models.PositiveIntegerField(null=True, blank=True, editable=False)
#FK
category = models.ManyToManyField(ProductCategory)
attribute_answers = models.ManyToManyField(AttributeAnswers)
# Custom Managers
def __unicode__(self):
return self.title
def qr_code(self):
return '' % self.qr_image.url
qr_code.allow_tags = True
def product_pre_save(sender, instance, **kwargs):
if not instance.pk:
instance._QRCODE = True
else:
if hasattr(instance, '_QRCODE'):
instance._QRCODE = False
else:
instance._QRCODE = True
models.signals.pre_save.connect(product_pre_save, sender=Product)
def product_post_save(sender, instance, **kwargs):
if instance._QRCODE:
instance._QRCODE = False
if instance.qr_image:
instance.qr_image.delete()
qr = QRCode(4, QRErrorCorrectLevel.L)
qr.addData(instance.qr_url)
qr.make()
image = qr.makeImage()
#Save image to string buffer
image_buffer = StringIO()
image.save(image_buffer, format='JPEG')
image_buffer.seek(0)
#Here we use django file storage system to save the image.
file_name = 'UrlQR_%s.jpg' % instance.id
file_object = File(image_buffer, file_name)
content_file = ContentFile(file_object.read())
instance.qr_image.save(file_name, content_file, save=True)
models.signals.post_save.connect(product_post_save, sender=Product)
Upvotes: 3
Views: 3242
Reputation: 3083
My approach is just to use udpate method of QuerySet object instead of save one from Model:
Model.objects.filter(pk=obj.pk).update(fieldx=valuey)
Upvotes: 0
Reputation: 416
To solve this problem, You should add one more field in database, this field will describe that inserted record is inserted by simple view or signal. then in receiver function you should check that if instance is inserted by signal if so don't apply receiver function
@receiver(post_save) def my_callback(using,sender,instance,**kwargs):
if not(instance.added_by == 'signal'):
obj = Student1()
obj.name = instance.name
obj.city = instance.city
obj.state = instance.state
obj.postal_code = instance.postal_code
obj.age = instance.age
obj.added_by = 'signal'
obj.save()
Upvotes: 0
Reputation: 4984
You copiend in wrong way from tutorial :)
def product_post_save(sender, instance, **kwargs):
if instance._QRCODE:
instance._QRCODE = False
if instance.qr_image:
instance.qr_image.delete()
qr = QRCode(4, QRErrorCorrectLevel.L)
qr.addData(instance.qr_url)
qr.make()
image = qr.makeImage()
#Save image to string buffer
image_buffer = StringIO()
image.save(image_buffer, format='JPEG')
image_buffer.seek(0)
#Here we use django file storage system to save the image.
file_name = 'UrlQR_%s.jpg' % instance.id
file_object = File(image_buffer, file_name)
content_file = ContentFile(file_object.read())
instance._already_saving = True
instance.qr_image.save(file_name, content_file, save=True)
Upvotes: 3
Reputation: 1906
Your post save signal call save which calls the post save signal which calls save ...
This is basically an infinite loop which the runtime kills with the Max Recursion error.
Upvotes: 5