2013-12-10 5 views
10

Ich habe ein Modell:Django REST Framework: Standardfelder in browseable API Form

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) 

und einen Serializer für dieses Modell:

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' 

Und hier ist die Listenansicht:

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) 

In browsenbare API CallList, sehe ich das folgende in das POST-Formular: enter image description here

Meine Frage ist: Warum gibt es keinen Standardwert für send_on, und es gibt einen für backup_calls? Ich nahm an, dass das Formular der XCall Modellspezifikation folgen würde und datetime.now() für das Ausfallen des ersteren verwenden und leer lassen (da es Nullable ist). Wie kann ich das Formular den Modellspezifikationen folgen lassen?

+0

Haben Sie dieses Problem jemals gelöst? Ich laufe gerade hinein. – user2734679

Antwort

3

Es gibt einen Unterschied zwischen Modellvorgaben und Anfangswerten in Formularen. Dies ist insbesondere bei Standardwerten der Fall, die eigentlich Funktionen sind, da sie nur beim Speichern der Instanz aufgerufen werden. Zum Beispiel, welche now möchten Sie - dieses Mal, wenn das leere Formular angezeigt wird, oder der Zeitpunkt, zu dem der Benutzer "POST" drückt? Django wendet den Standard beim Speichern des Modells an, wenn der Feldwert fehlt. Um das zu erreichen, was Sie wollen Sie müssen manuell den Standard im serialize Feld gesetzt, zum Beispiel:

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

Ich bin mir nicht sicher, ob ich das Verhalten sehe, das du beschreibst. Wenn ich versuche, ohne send_on zu schreiben, bekomme ich einen Validierungsfehler "Dieses Feld ist erforderlich". Wenn Sie sagen, Django wendet den Standard beim Speichern an, warum der Validierungsfehler? Einige andere Informationen: 1) Ich bin auf Django 1.6; Ich erinnere mich vage daran, dass das alles anders funktioniert, bevor ich von 1.4 upgrade. 2) Seltsamerweise sehe ich die Standard-Formularwerte so, wie ich es im Django-Entwicklungsmodus erwarte, aber nicht in meinem Produktionsumfeld (Django + Apache + mod_wsgi). – Neil

+0

Und diese Antwort erklärt auch nicht, warum ich einen Standardwert für das Feld "backup_calls" sehe. Ich setze es nicht explizit in CallSerializer. – Neil

+1

IIRC, Feld Validierung zuerst passiert in der Form. Das Formular sieht, dass nichts in send_on eingegeben wurde, es ist erforderlich und gemäß dem Formularfeld gibt es keinen Standardwert, sodass eine Ausnahme ausgelöst wird, bevor das Modell aufgerufen wird. Ich weiß nicht, warum es in der Produktion anders funktionieren würde - klingt, als könnte es ein seltsames Caching-Problem sein. – aquavitae

2

Sie wollen tatsächlich einen initial Wert setzen, ist kein Standardwert. Siehe docs. Ihr Code sollte sein:

Ein Standardwert ist der Wert für ein Attribut, wenn für das Feld kein Wert festgelegt ist Die Unterscheidung zwischen initial und default Argumente spiegelt den Unterschied zwischen Djangos initial Argument für Formularfelder und Djangos default Argument für Modellfelder wider.