2014-04-24 15 views
1

Mes utilisateurs peuvent créer une ou plusieurs listes avec des éléments.Django REST-framework: Rendre un champ facultatif

J'utilise django REST-framework et sous-classe de la « viewsets.ModelViewSet » pour recevoir un objet jsonlist_item qui a comme foreign key: le champ de liste.

Voici ce que je veux faire:

  • créer automatiquement une nouvelle liste lorsqu'un messages de l'utilisateur son premier élément. Pour le moment, cela crée une erreur car l'identifiant de la liste est requis.
  • Affichage l'identifiant de liste devrait être en option (de sorte que les utilisateurs peuvent poster plus d'une liste)

TestCode (simplifié):

test_posting_item_creates_list(self): 
    item = { 
     'name': "test", 
    # 'list': 1, 
     'user': self.user.id, 

    } 
    response = self.client.post('/api/listitems/', 
         json.dumps(item), 
         content_type="application/json") 
    self.assertEqual(response.status_code, 201, 'statuscode is 201 created') 

Ceci est mon sérialiseur

class ItemSerializer(serializers.ModelSerializer): 

    # this works for changing the list but a list field is required when posting 
    def validate(self, attrs):  
     if 'list' in attrs: 
      attrs['list'] = TodayList.objects.create() 


    class Meta: 
     model = TodayListItem 
     fields =('id', 
       'name', 
       'user', 
       'list', 
    ) 

Avec ma méthode validate je peux changer la liste, à un autre, donc j'ai essayé: if 'list' not in attrs: mais cela ne fonctionne pas.

Le sérialiseur est-il le bon endroit pour "intercepter" le message et créer la liste? Comment puis-je rendre un champ facultatif?

Répondre

0

Basé sur le manuel de framework Django REST

validation sur le terrain

Vous pouvez spécifier la validation de niveau champ personnalisé en ajoutant méthodes .validate_ à votre sous-classe sérialiseur. Ce sont analogue aux méthodes .clean_ sur les formulaires Django, mais acceptent des arguments légèrement différents.

ils prennent un dictionnaire d'attributs désérialisées comme un premier argument, et le nom du champ en ce que le dictionnaire comme un second argument (qui être le nom du champ ou de la valeur de l'argument de la source à le champ , si un était fourni).

Ainsi, la solution est de créer une méthode de validation de la liste comme ceci:

def validate_list(self, attrs, source): 
    """ 
    Check that the list is correct or not? 
    """ 
    if list not in attrs: 
     list_item = TodayList.objects.create() 
     list = list_item.id 
    return attrs 

Une autre solution est dans le niveau du modèle, en remplaçant la save() et vérifiez l'identifiant de liste.

def save(self, *args, **kwargs): 
    if self.list is None: 
     self.list = TodayList.objects.create() 
    super(TodayListItem, self).save(*args, **kwargs) # Call the "real" save() method. 
+0

Votre deuxième solution fonctionne en partie: Je peux créer des éléments sans poster un identifiant de liste dans l'objet JSON, mais je dois enlever le champ de liste du 'ItemSerializer' ainsi je ne peux pas le placer avec le poteau. (J'ai aussi besoin d'utiliser 'if self.list_id est None: 'dans la méthode save du modèle car il s'agit d'une clé primaire) – ddd

+0

Qu'en est-il du premier? ne fonctionne pas? assurez-vous de supprimer la fonction validate() avant de l'utiliser. Incluez également la classe TodayList dans le fichier. Faîtes-moi savoir si vous avez besoin de quoi que ce soit. – Othman

0

Dans votre sérialiseur vous pouvez marquer vos champs comme non nécessaire en passant required arguments False

class UserResponse(ModelSerializer): 
    response = IntegerField() 
    meta_data = MetaDataSerializer(allow_null=True, required=False) 
Questions connexes