【问题标题】:Django model error maximum recursion depth exceededDjango模型错误超出最大递归深度
【发布时间】:2013-02-19 16:41:24
【问题描述】:

我正在关注这个guide,保存时出现以下错误...

RuntimeError at /admin/products/product/2/
maximum recursion depth exceeded

为什么会出现此错误?我在下面包含了完整的模型。

谢谢

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)

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    你的 post save 信号调用 save 调用 post save 信号调用 save ...

    这基本上是一个无限循环,运行时会因最大递归错误而终止。

    【讨论】:

      【解决方案2】:

      你从教程中以错误的方式复制:)

      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)
      

      【讨论】:

        【解决方案3】:

        为了解决这个问题,你应该在数据库中增加一个字段,这个字段将描述插入的记录是由简单的视图或信号插入的。然后在接收器函数中,您应该检查是否通过信号插入了实例,如果是,则不要应用接收器函数

        @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()
        

        【讨论】:

        • 这不是一个好主意,因为您必须添加一个在其他地方未使用的额外字段,并且您将对该模型进行迁移。如果我们需要为 100 多个模型做些什么呢?
        【解决方案4】:

        我的方法只是使用 QuerySet 对象的 udpate 方法,而不是从模型中保存一个:

        Model.objects.filter(pk=obj.pk).update(fieldx=valuey)
        

        【讨论】:

          猜你喜欢
          • 2016-12-10
          • 2018-03-04
          • 1970-01-01
          • 2017-08-09
          • 2011-03-31
          • 2018-12-03
          • 2018-01-14
          • 2017-07-18
          • 2021-12-11
          相关资源
          最近更新 更多