2013-12-10 7 views
10

Mam model:Django REST ramowa: domyślne pola browseable formie API

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) 

a serializatora dla tego modelu

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' 

A oto widok listy:

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) 

Interfejs API do przeglądania dostępny w CallList, widzę na dole w formularzu POST: enter image description here

Moje pytanie brzmi: dlaczego nie ma wartości domyślnej dla send_on, a jest jedna dla backup_calls? Założono, że formularz będzie zgodny ze specyfikacją modelu XCall i użyje datetime.now() do domyślnego ustawienia poprzedniego i pozostawi puste (ponieważ jest zerowalne). Jak mogę uzyskać formularz zgodny ze specyfikacjami modelu?

+0

Czy kiedykolwiek rozwiązałeś ten problem? W tej chwili używam go. – user2734679

Odpowiedz

3

Istnieje rozróżnienie między wartościami domyślnymi modelu i wartościami początkowymi w formularzach. Dotyczy to w szczególności wartości domyślnych, które w rzeczywistości są funkcjami, ponieważ są wywoływane tylko wtedy, gdy instancja jest zapisywana. Na przykład, który numer now chcesz - ten czas, w którym wyświetlany jest pusty formularz, lub czas, w którym użytkownik naciśnie "POST"? Django stosuje ustawienie domyślne podczas zapisywania modelu, jeśli brakuje wartości pola. Aby osiągnąć to, co chcesz, musisz ręcznie ustawić wartość domyślną w polu serializacji, na przykład:

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

Nie jestem pewien, czy widzę zachowanie, które opisujesz. Gdy próbuję publikować bez wypełnienia pola send_on, pojawia się komunikat o błędzie "To pole jest wymagane". Jeśli mówisz, że Django stosuje domyślne ustawienie zapisu, dlaczego błąd sprawdzania poprawności? Kilka innych informacji: 1) Jestem na Django 1.6; Niejasno pamiętam, że wszystko to działa inaczej, zanim uaktualniłem wersję 1.4. 2) O dziwo widzę domyślne wartości formularzy działające tak, jak oczekuję w trybie programowania Django, ale nie w moim env produkcyjnym (Django + Apache + mod_wsgi). – Neil

+0

Ta odpowiedź również nie wyjaśnia, dlaczego widzę wartość domyślną dla pola 'backup_calls'. Nie jestem jawnie ustawienie go w 'CallSerializer' – Neil

+1

IIRC, walidacja pola najpierw dzieje się w formularzu. Formularz widzi, że nic nie zostało wprowadzone do send_on, jest wymagane i zgodnie z polem formularza nie ma wartości domyślnej, więc przed przejściem do modelu wywołuje wyjątek. Nie wiem, dlaczego miałoby to działać inaczej w produkcji - wydaje się, że może to być jakiś dziwny problem z pamięcią podręczną. – aquavitae

2

rzeczywiście chcesz ustawić wartość initial, a nie wartość domyślną. Zobacz docs. Twój kod powinien być:

from django.utils import timezone 


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

Wartość domyślna to wartość dostarczona do atrybutu, jeśli dla pola nie ustawiono żadnej wartości. Rozróżnienie między argumentami initial i default odzwierciedla różnicę między argumentem Django o wartości initial dla pól formularza i argumentem Django dla default dla pól modelu.