Как сериализовать уже существующее изображение для сохранения в параметре models.ImageField?

Я хочу создать Note объект, одним из полей модели которого является ImageField, используя Django Rest Framework. Я уже могу создавать объекты и обновлять все различные поля, используя мой API, кроме изображений.

Мой код:

models.py

class Note(OwnedModel):
    note_id = models.UUIDField(primary_key=True,
                               default=uuid.uuid4,
                               editable=False)
    # note_owner = models.ForeignKey(, null=True, blank=True, on_delete=models.SET_NULL)
    note_name = models.CharField(max_length=50)
    body = models.TextField()
    updated = models.DateTimeField(auto_now=True)
    created = models.DateTimeField(auto_now_add=True)
    qr_image        = models.ImageField(upload_to='notes', null=True)


    def __str__(self):
        return self.note_name[0:50]

    class Meta:
        ordering = ['-updated']

views.py

@api_view(['GET', 'POST'])
def getNote(request, pk=None):
    if request.method == 'GET':
        note = Note.objects.get(note_id=pk)
        serializer = NoteSerializer(note, many=False)
        return Response(serializer.data)

    elif request.method == 'POST':

        _data = request.data.copy()
        owner = request.user.id
        _data["owner"] = owner

        # Generate QR code
        qr_image = generate_qr(_data["note_name"])

        # HOW TO PASS THE IMAGE TO THE SERIALIZER?
        _data["qr_image"] = qr_image
        # _data["qr_image"] = qr_image[0]
        # _data["qr_image"] = qr_image[1]


        serializer = NoteSerializer(data=_data)
        
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)

        return Response(status=status.HTTP_400_BAD_REQUEST)

serializers.py

class NoteSerializer(ModelSerializer):
    class Meta:
        model = Note
        fields = '__all__'

qr_code.py

import qrcode

def generate_qr(qr_file_name=None):

    qr = qrcode.QRCode(
        version=1,
        # error_correction=qrcode.constants.ERROR_CORRECT_L,
        box_size=4,
        border=3,
    )
    qr.add_data(qr_file_name)
    qr.make(fit=True)
    img = qr.make_image()
    # img = qr.make_image(fill_color="black", back_color="white")
    path='images/notes/'+str(qr_file_name)+'.jpg'
    img.save(path)

    return path, img

QR-код сгенерирован правильно и сохранен в пути загрузки идеально.

Не получается правильно построить строку _data["qr_image"] = qr_image, или если нужно вернуть изображение другим способом из функции generate_qr. Все остальное работает хорошо (например, создание объекта Note из формы Admin и загрузка qr-изображения).

@api_view(['GET', 'POST'])
def getNote(request, pk=None):
    if request.method == 'GET':
        # automatically raise 404 if obj does not exist
        note = get_object_or_404(Note.objects, note_id=pk)

        # many=False is default, dont need that
        serializer = NoteSerializer(note)
        return Response(serializer.data)

    elif request.method == 'POST':
        serializer = NoteSerializer(data=request.data)

        # raise_exception=True will raise validation error (400) automatically
        serializer.is_valid(raise_exception=True)
        
        # get note name after validation to be sure it has proper length etc.
        qr_image = generate_qr(serializer.validated_data.get("note_name"))

        # attributes provided here will bypass validation
        # and will be injected directly to model create method
        serializer.save(
            owner=request.user,
            qr_image=qr_image
        )
        return Response(serializer.data, status=status.HTTP_201_CREATED)

Я не уверен, что ваша функция generate_qr должна сохранять изображение по заданному пути, потому что Note должна делать это за вас при создании.

Совет: проверьте класс viewsets.GenericViewSet - он правильно разделит ваше представление на методы и облегчит жизнь.

Вернуться на верх