2014-08-28 6 views
2

Je veux mettre à jour un modèle en utilisant djangorestframework. Je n'ai pas besoin de mettre à jour tous les champs, donc j'utilise PATCH. Cependant, dans ma forme j'ai aussi un champ d'image (appelé «logo»), qui est requis pour mon modèle. Lorsque j'essaie de 'patcher' l'objet et que je ne choisis pas une nouvelle image pour ce champ, drf renvoie une erreur ('logo': 'Ce champ est obligatoire').Comment mettre à jour ImageField/FileField en utilisant djangorestframework?

Je sais que lorsque vous utilisez des formulaires django, les champs de fichiers reçoivent un traitement spécial, ce qui signifie que s'ils ont déjà une valeur, soumettre le formulaire avec un champ de fichier vide conservera simplement l'ancienne valeur. Est-il possible de faire cela en utilisant des sérialiseurs djangorestframework?

Une partie du code pour une meilleure compréhension:

# models.py 
class Brand(models.Model): 
    name = models.CharField(_('name'), max_length=250) 
    logo = models.ImageField(upload_to='brands/') 

# serializers.py 
class BrandSerializer(serializers.ModelSerializer): 

    class Meta: 
     model = Brand 
     fields = (
      'id', 
      'name', 
      'logo', 
     ) 

# detail.html 
<form method="post" enctype="multipart/form-data"> 
    {%csrf_token%} 

     <input name="name" type="text" maxlength="30" value="{{ brand.name }}"/> 
     <input name="logo" type="file" accept="image/*"/> 

    <input name="_method" type="hidden" value="PATCH"> 
    <input type="submit" value="Update"/> 

</form> 

Le mieux que je pouvais venir avec pour l'instant était de supprimer l'entrée de mon request.DATAlogo avant d'appeler le sérialiseur. Je suis curieux de savoir si quelqu'un connaît une meilleure solution. Merci.

Répondre

3

Essayez Link espérons pleinement que vous obtiendrez une solution. Ou Voir ce cade, espérons pleinement que cela fonctionnera pour vous.

class ImageSerializer(serializers.HyperlinkedModelSerializer): 
    class Meta: 
     model = Brand 
     fields = ('name', 'logo') 
    def saveImage(self, imgFileUri): 
     #parse dataUri and save locally, return local path 
     return 'somewhereOverTheBlah' 

    def restore_fields(self, data, files): 

     reverted_data = {} 

     if data is not None and not isinstance(data, dict): 
      self._errors['non_field_errors'] = ['Invalid data'] 
      return None 

     for field_name, field in self.fields.items(): 
      """ 
      So it is iterating over the fields to serialize, when we find the file field 
      do something different (in this case look for the fileUri field, handle it and replace 
      it inside of the reverted_data dictionary with the intended file field 
      """ 

      if(field_name == 'file'): 
       field_name = 'dataUri' 
       field = fields.CharField() 
       try: 
        # restore using the built in mechanism 
        field.field_from_native(data, files, field_name, reverted_data) 
        # take the dataUri, save it to disk and return the Path 
        value = reverted_data[field_name] 
        path = self.saveImage(value) 
        # set the file <Path> property on the model, remove the old dataUri 
        reverted_data['file'] = path 
        del reverted_data[field_name] 

       except ValidationError as err: 
        self._errors[field_name] = list(err.messages) 
      else: 
       field.initialize(parent=self, field_name=field_name) 
       try: 
        field.field_from_native(data, files, field_name, reverted_data) 
       except ValidationError as err: 
        self._errors[field_name] = list(err.messages) 

     return reverted_data 
Questions connexes