2015-01-22 12 views
9

Esistono due modelli: Product e Picture. Ogni Product può avere diversi Picture s. Ho delle domande quando voglio creare un prodotto usando POST. Come pubblicare un oggetto nidificato contenente un elenco ImageField?Come inviare un dati nidificati e un elenco di immagini

Il modello Product è:

class Product(models.Model): 
    product_id = models.AutoField(primary_key=True) 
    product_name = models.CharField(max_length=50) 
    description = models.TextField(blank=True) 

Il modello Picture è:

class Picture(models.Model): 
    product = models.ForeignKey(Product, related_name='pictures') 
    path = models.ImageField(null=False, upload_to='product_pic') 
    description = models.CharField(max_length=255, null=True, blank=True) 
    main = models.BooleanField() 

scrivo la serializer.py come segue:

class PictureSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Picture 
     fields = ('path', 'description', 'main') 

class ProductSerializer(serializers.ModelSerializer): 
    pictures = PictureSerializer(many=True, required=False) 

    class Meta: 
     model = Product 
     fields = ('product_id', 'product_name', 'pictures', 'description') 

Il punto di vista che sto usando is:

class ProductEnum(generics.ListCreateAPIView): 
    queryset = Product.objects.all() 
    serializer_class = ProductSerializer 
    permission_classes = (IsAuthenticated,) 

    def post(self, request, format=None): 
     serializer = ProductSerializer(data=request.DATA, files=request.FILES) 

     if serializer.is_valid(): 
      serializer.save() 
      return Response(serializer.data, status=status.HTTP_201_CREATED) 
     return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 

sto registrando che negli URL come:

url(r'^api/products/$', views.ProductEnum.as_view()), 

Le domande sono:

  • Come potrei provare questo post api come django-rest-framework mi dice che "Le liste non sono attualmente supportate in Input HTML "
  • Come utilizzare JSON per POST a Product risorse con più Pictures. O devo usare parser multipart.
  • Come scrivere il comando cURL?
+1

sei riuscito a farlo bene? – momokjaaaaa

risposta

0

È possibile utilizzare shell manage.py. Ti piace questa:

import requests 
r = requests.post("http://localhost:8000/login/url", data={"username": "username", "password": "password"} 
r.content (outputs token) 
token="yourtoken" 
r = requests.post("http://localhost:8000/your/url", data={your POST data in json}, headers={"Authorization": "Token %s" % token}) 
+0

Non hai risposto alla domanda d'oro del poster - Come usare JSON per POSTARE le risorse di un prodotto con più immagini. O devo usare parser multipart. – momokjaaaaa

0

DRF rende abbastanza facile da fare. Vi sono vicino, è necessario eseguire l'override ProductSerializer.create, qualcosa di simile:

class ProductSerializer(serializers.ModelSerializer): 
    pictures = PictureSerializer(many=True, required=False) 

    class Meta: 
     model = Product 
     fields = ('product_id', 'product_name', 'pictures', 'description') 

    def create(self, validated_data): 
     # Pop this from the validated_data first, since the serializer can't handle it. 
     pictures = validated_data.pop('pictures') 
     product = super().create(validated_data) 
     # Now that we have a product to reference in the FKey, create the pictures. 
     for picture in pictures: 
      # `picture` has been run through the PictureSerialzer, so it's valid. 
      picture['product'] = product 
      Picture.objects.create(**picture) 
     return product 

C'è un esempio completo nella documentazione, qui: http://www.django-rest-framework.org/api-guide/relations/#writable-nested-serializers

Per il vostro comando curl, sta andando essere qualcosa di simile:

curl -X POST http://localhost:8000/products/ -H 'ContentType: application/json' -d '{"pictures": [{"description": "first one"}, {"description": "second one"}], "product_name": "foobar"}'

2

Devi usare parser multipart, non appena è necessario inviare i dati binari che, fondamentalmente, hai solo a scelte:

  1. indebolire il vostro approccio REST e fare un'eccezione -> JSON non può contenere dati binari
  2. codificare tutti i file binario con Base64, mantenere approccio JSON, ma è necessario fare de/encoding in aggiunta, per ogni richiesta (non nativamente supportato)

un approccio che può essere visto molto spesso è quello di creare un (non riposo) al fine di caricare singoli file/multipli che creano File o Document oggetti (che ritornano un ID durante il caricamento). Quindi puoi usare questi id che sono un'altra richiesta, nel tuo caso creando/aggiornando il tuo Product.

In generale, non esiste un modo semplice per farlo perché JSON non supporta i dati binari.

Problemi correlati