2013-12-10 10 views
10

Ho un modello:Django REST quadro: campi predefiniti in forma API browseable

class XCall(models.Model): 
    created_on = models.DateTimeField(auto_now_add=True) 
    send_on = models.DateTimeField(default=datetime.now) 
    recipient = models.ForeignKey(User) 
    text = models.CharField(max_length=4096) 
    backup_calls = models.IntegerField(blank=True, null=True) 

E un serializzatore per il modello:

class CallSerializer(serializers.HyperlinkedModelSerializer): 
    url = serializers.HyperlinkedIdentityField(
     view_name='call-detail', 
    ) 
    # some validation and custom field definitions 
    ... 

    class Meta: 
     model = XCall 
     fields = ('url', 'id', 'text', 'recipient', 'send_on', 'backup_calls', 'status') 
     lookup_field= 'pk' 

Ed ecco la visualizzazione elenco:

class CallList(generics.ListCreateAPIView): 
    serializer_class = CallSerializer 
    permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrSuperuser,) 

    def pre_save(self, obj): 
     auth_user = self.request.user 
     obj.auth_user = auth_user 

    def get_queryset(self): 
     """ 
     This view should return a list of all the calls 
     for the currently authenticated user. 
     """ 
     auth = self.request.user 
     if isinstance(auth, AnonymousUser): 
      return [] 
     elif auth.is_superuser: 
      return XCall.objects.all() 
     else: 
      return XCall.objects.filter(auth_user=auth) 

Nell'API navigabile di CallList, vedo quanto segue nel modulo POST in basso: enter image description here

La mia domanda è: perché non esiste un valore predefinito impostato per send_on e ce n'è uno per backup_calls? Ho assunto che il modulo seguisse le specifiche del modello XCall e usasse datetime.now() per l'impostazione predefinita del primo e lascia vuoto lo backup_calls (poiché è annullabile). Come posso ottenere il modulo per seguire le specifiche del modello?

+0

Hai mai risolto questo problema? Al momento ci sto provando. – user2734679

risposta

3

C'è una distinzione tra valori predefiniti del modello e valori iniziali nei moduli. Questo è particolarmente vero per i valori di default che sono in realtà funzioni perché vengono chiamati solo quando l'istanza viene salvata. Ad esempio, quale now vuoi: questa volta in cui viene visualizzato il modulo vuoto o l'ora in cui l'utente preme "POST"? Django applica il valore predefinito quando salva il modello se il valore del campo è mancante. Per ottenere ciò che si vuole è necessario impostare manualmente il valore di default nel campo Serialize, ad esempio:

class CallSerializer(serializers.HyperlinkedModelSerializer): 
    send_on = serializers.DateTimeField(default=datetime.now) 
    ... 
+0

Non sono sicuro di vedere il comportamento che descrivi. Quando provo a postare senza send_on compilato, viene visualizzato un errore di convalida "Questo campo è obbligatorio". Se stai dicendo che Django applica il valore predefinito al salvataggio, perché l'errore di convalida? Alcune altre informazioni: 1) Sono su Django 1.6; Ricordo vagamente che tutto questo ha funzionato in modo diverso prima di aggiornare da 1.4. 2) Stranamente, vedo i valori dei moduli predefiniti che funzionano come mi aspetto in modalità di sviluppo Django, ma non nella mia produzione env (Django + Apache + mod_wsgi). – Neil

+0

Inoltre, questa risposta non spiega perché vedo un valore predefinito per il campo 'backup_calls'. Non lo imposto esplicitamente in 'CallSerializer' – Neil

+1

IIRC, la convalida dei campi avviene prima nel modulo. Il modulo vede che non è stato inserito nulla in send_on, è richiesto e in base al campo modulo non esiste un valore predefinito, quindi solleva un'eccezione prima di arrivare al modello. Non so perché funzionerebbe diversamente in produzione però - sembra che potrebbe essere un problema di caching strano. – aquavitae

2

si vuole realmente impostare un valore initial, non un valore predefinito. Vedi lo docs. Il tuo codice dovrebbe essere:

from django.utils import timezone 


class CallSerializer(serializers.HyperlinkedModelSerializer): 
    send_on = serializers.DateTimeField(initial=timezone.now()) 
    ... 

Un valore predefinito è il valore fornito per un attributo se non è impostato alcun valore per il campo. La distinzione tra gli argomenti initial e default rispecchia la differenza tra l'argomento initial di Django per i campi modulo e l'argomento default di Django per i campi del modello.

Problemi correlati