超过最大递归深度,保存方法,Django

nas*_*yn8 3 python django

尝试使用 Python3.4 使用 QR-code 5.3 生成 QR 码时。我面临几个问题:

起初我使用 io.StringIO 并且我得到了一个预期字符串参数,得到了 'bytes'错误消息。所以我然后将 io.StringIO 更改为 io.BytesIO。然后我得到了另一个错误,它是'_io.BytesIO' 对象没有属性 'len'所以为了获得我使用的对象的长度buffer.getbuffer().nbytes但现在我得到了最大递归深度超过和它生成了 298 张二维码图像,而不仅仅是一张。任何想法我做错了什么?

from django.db import models
from django.conf import settings
from django.core.urlresolvers import reverse
from django.core.files.uploadedfile import InMemoryUploadedFile

import random
import qrcode
import io
import sys

from PIL import Image

import pdb;


def qrcode_location(instance, filename):
    return '%s/qr_codes/%s' % (instance.user.username, filename)


# Create your models here.
class EmployeeProfile(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL,  on_delete=models.CASCADE)
    qrcode = models.ImageField(upload_to=qrcode_location, null=True, blank=True)
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

    def __str__(self):
        return self.first_name + ' ' + self.lastname

    def save(self):
        first_initial = self.first_name[0].upper()
        second_initial = self.last_name[0].upper()
        id_number = first_initial + second_initial + str(random.randint(1000000, 9999999))
        self.generate_qrcode()

        if not EmployeeProfile.objects.filter(employee_id=id_number).exists():
            self.employee_id = id_number
            super(EmployeeProfile, self).save()

    def generate_qrcode(self):
        qr = qrcode.QRCode(
            version=1,
            error_correction=qrcode.constants.ERROR_CORRECT_L,
            box_size=10,
            border=4,
        )
        qr.add_data('Some data')
        qr.make(fit=True)

        img = qr.make_image()

        buffer = io.BytesIO()
        img.save(buffer)
        filename = 'qrcode.png'
        filebuffer = InMemoryUploadedFile(buffer, None, filename, 'image/png', buffer.getbuffer().nbytes, None)
        self.qrcode.save(filename, filebuffer)
Run Code Online (Sandbox Code Playgroud)

--------------------解决方案更新---------------------------- ---

由于 save 正在调用 generate_qrcode,并且调用 self.qrcode.save 并且模型调用 save 导致无限递归。因此,为了防止发生这种情况,您只需要通过向 FileField 的 save 方法提供额外的第三个参数来绕过它。

调用Python对象时超出模型最大递归深度中的Django FileField

# set 3 argument to false(save=False) otherwise infinite recursion will happen
self.qrcode.save(filename, filebuffer, False)
Run Code Online (Sandbox Code Playgroud)

Ale*_*all 5

self.qrcode.save意味着需要保存整个模型对象,因此它会导致调用savewhich 调用generate_qrcodewhich 调用self.qrcode.save...(顺便说一下,您应该能够在回溯中看到这一点),因此您的问题与BytesIO. 在某处插入条件以中断递归循环。