2014-10-31 11 views
5

Quindi ho cercato di caricare un file su un metodo utilizzando DRF senza fortuna fino ad ora.Django Rest Framework carica il file su un metodo

sono stato in grado di caricare su un ModelViewSet utilizzando (FormParser, MultiPartParser,) senza problemi, ma ho davvero bisogno di utilizzarlo in qualcosa di simile http://localhost:8000/api/v1/women/{pk}/upload_avatar/ dove voglio filtrare prima la donna da id e caricare sul suo avatar (che è una straniera chiave per un modello multimediale). Ho provato a utilizzare una libreria di risorse nidificata senza fortuna.

finora ho nel mio modelviewset:

class WomenNativePassportViewSet(viewsets.ModelViewSet): 
    queryset = Women.objects.all() 
    serializer_class = WomenNativePassportSerializer 
    authentication_classes = (NoAuthentication,) 
    permission_classes = (AllowAny,) 
    parser_classes = (FormParser, MultiPartParser,) 

    @detail_route(
     methods=['post', 'put', 'patch', 'get'], permission_classes=[AllowAny], 
     authentication_classes=[NoAuthentication], serializer_class=MultimediaSerializer, 
     parser_classes=(FormParser, MultiPartParser,) 
    ) 
    def upload_avatar(self, request, pk=None, *args, **kwargs): 
     if 'POST' in request._method or 'PATCH' in request._method: 
      # Write code to save the file?? 
     else: 
      multimedia = Multimedia.objects.filter(user_profiles_avatares__pk=pk) 
      page = self.paginate_queryset(multimedia) 
      serializer = self.get_pagination_serializer(page) 
     return Response(serializer.data) 

I miei modelli:

class Women(models.Model): 
    user = models.OneToOneField(settings.AUTH_USER_MODEL) 
    avatar = models.ForeignKey(
     'core.Multimedia', blank=True, null=True, 
     related_name='user_profiles_avatares' 
    ) 

class Multimedia(models.Model): 
    file = models.FileField(upload_to=upload_to, null=True, blank=True) 
    thumbnail = models.FileField(upload_to=upload_to, null=True, blank=True) 

In sostanza vorrei sapere se questa è la strada giusta sto prendendo, e se sì, come posso salvare correttamente il file caricato nel modello ??

risposta

6

Ecco un codice di ciò che ho fatto per risolvere questo problema. Anche se la risposta di Kevin Brown probabilmente funziona, trovo il mio codice un approccio "più semplice":

@detail_route(
     methods=['post', 'put', 'patch', 'get'], permission_classes=[AllowAny], 
     authentication_classes=[NoAuthentication], serializer_class=MultimediaSerializer, 
     parser_classes=(FormParser, MultiPartParser,) 
    ) 
    def upload_avatar(self, request, pk=None): 
     # Because we are using nested resources this was the only way i found to 
     # upload a file. Maybe there is a better way 
     if request.method in ['PATCH', 'POST']: 
      avatar = request.FILES.get('avatar') 
      if not avatar: 
       return Response(status=404) 

      try: 
       woman = WomenNativePassport.objects.get(pk=pk) 
      except WomenNativePassport.DoesNotExist: 
       return Response(status=404) 
      else: 
       request.FILES['thumbnail'] = request.FILES['avatar'] 
       serializer = AvatarSerializer(
        data=request.DATA, files=request.FILES 
       ) 
       if serializer.is_valid(): 
        woman.avatar.thumbnail.save(str(avatar), File(avatar)) 
        return Response(status=204) 
       else: 
        return Response(status=404) 
     else: 
      multimedia = Multimedia.objects.filter(user_profiles_avatares__pk=pk) 
      page = self.paginate_queryset(multimedia) 
      serializer = self.get_pagination_serializer(page) 
      return Response(serializer.data) 


# serializer 

class AvatarSerializer(serializers.Serializer): 
    thumbnail = serializers.ImageField() 
+4

Suggerisco di cambiare il controllo del metodo in modo che assomigli a 'if request.method in ['PATCH', 'POST']', poiché 'request.method' è sempre un metodo unico. – gregoltsov

0

Tutti i file caricati devono essere disponibili in request.FILES, un dizionario digitato dal campo che sono stati utilizzati durante il caricamento. Una volta ottenuto il file, si tratta di gestirlo come qualsiasi altro uploaded file in Django.

Se possibile, vorrei utilizzare un secondo serializzatore che avvolge il modello Multimedia in modo che la convalida e il salvataggio dell'immagine possano essere eseguiti automaticamente tramite Django REST Framework. C'è an ImageField che convaliderà automaticamente l'immagine tramite Pillow che è possibile utilizzare sul serializzatore.

+0

questo ti sembra giusto? http://paste.ubuntu.com/8760416/ – psychok7

Problemi correlati