2017-05-29 59 views
1

我可以上传现场的时间和员工,但我不能上传图片到attendance_pic如何通过请求上传图片:Python的Django的REST框架

型号

class Attendance(models.Model): 
    time = models.DateTimeField(default=datetime.now, blank=True) 
    employee = models.ForeignKey(Employee, related_name='employees') 
    attendance_pic = models.ImageField(upload_to='attendance_pics',null = True) 

串行器

class AttendanceSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Attendance 
     fields = '__all__' 

查看

class AttendanceList(APIView): 
    def get(self,request): 
     model = models.Attendance 
     attendances = model.objects.all() 
     serializer = AttendanceSerializer(attendances, many = True) 
     return Response(serializer.data) 

    def post(self,request): 
     now = timezone.now() 
     serializer = AttendanceSerializer(data=request.data) 
     serializer.is_valid(raise_exception=True) 
     if serializer.is_valid(): 
      serializer.save(time=now) 
      # print (serializer.validated_data) 
      # emp = serializer.validated_data.get("employee") 
      # obj = models.Attendance.objects.create(time=now, employee=emp) 
      return Response("Success", status=status.HTTP_201_CREATED) 
      # return Response(AttendanceSerializer(obj).data, status=status.HTTP_201_CREATED) 
     return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 

请求

f = open("pic.jpg","rb") 
r = requests.post(self.url,data={"employee":ID,"attendace_pic":f}) 

如果我编码f控制base64.encodebase64,串行器将允许request.data但它将成为我无法解码它,如果我只是通过它没有编码串行器将不会允许。

或者我应该使用FileUploadParser

+0

是什么意思,你无法解码呢?你能告诉我们你的请求处理代码和发生了什么吗? – AlVaz

+0

@AlVaz结果如果使用** base64.encodebase64 ** {'employee':['25'],'attendance_pic':['/ 9j/4AAQSkZJ ...']} 但是当我使用** decodebase64 **,结果是**无**(我认为它不通过串行器) 接下来应该怎么做? –

回答

0

最后,我找到了正确这个问题的一些代码。从THIS!

请求

f = open("pic.jpg","rb") 
data = f.read() 
data_url = "data:image/jpg;base64,%s" % base64.b64encode(data) 
data_url = data_url[0:22] + data_url[24:] 
print(data_url[0:50]) 
r = requests.post(self.url,data={"employee":ID, "attendance_pic":data_url}) 
f.close() 

Serializers.py

from rest_framework import serializers 
from .models import Attendance 
from django.core.files.base import ContentFile 
import base64 
class Base64ImageField(serializers.ImageField): 
    def to_internal_value(self, data): 
     from django.core.files.base import ContentFile 
     import base64 
     import six 
     import uuid 
     print("ininternal") 
     # Check if this is a base64 string 
     if isinstance(data, six.string_types): 
      # Check if the base64 string is in the "data:" format 
      print("ininstance") 
      if 'data:' in data and ';base64,' in data: 
       # Break out the header from the base64 content 
       header, data = data.split(';base64,') 

      # Try to decode the file. Return validation error if it fails. 
      try: 
       decoded_file = base64.b64decode(data) 
      except TypeError: 
       self.fail('invalid_image') 

      # Generate file name: 
      file_name = str(uuid.uuid4())[:12] # 12 characters are more than enough. 
      # Get the file name extension: 
      file_extension = self.get_file_extension(file_name, decoded_file) 

      complete_file_name = "%s.%s" % (file_name, file_extension,) 

      data = ContentFile(decoded_file, name=complete_file_name) 

     return super(Base64ImageField, self).to_internal_value(data) 

    def get_file_extension(self, file_name, decoded_file): 
     import imghdr 

     extension = imghdr.what(file_name, decoded_file) 
     extension = "jpg" if extension == "jpeg" else extension 

     return extension 

class AttendanceSerializer(serializers.ModelSerializer): 

    attendance_pic = Base64ImageField(
     max_length=None, use_url=True, 
    ) 

    class Meta: 
     model = Attendance 
     fields = ('__all__') 
相关问题