I want to create Note
object which one of the fields of the model is an ImageField
using Django Rest Framework.
I can already create objects and update all different fields using my API, except for images.
My code:
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
The QR code is properly generated and saved in the upload path perfectly.
What I cannot manage to build line _data["qr_image"] = qr_image
correctly, or if I need to return the image in a different way from the generate_qr
function. Everything else it is working well (for example create the Note
object form the Admin and uploading the qr image).
CodePudding user response:
@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)
Im not sure that your generate_qr
function should save image in the given path because Note
should do it for you on create.
Tip: check the viewsets.GenericViewSet
class - it will properly split your view into methods and makes the life easier.