Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django REST Framework: default fields in browseable API form

I have a model:

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)

And a serializer for that model:

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'

And here's the list view:

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 CallList's browseable API, I see the following in the POST form at the bottom: enter image description here

My question is: why is there no default value set for send_on, and there is one for backup_calls? I assumed that the form would follow the XCall model specification and use datetime.now() for defaulting the former, and leave backup_calls blank (since it's nullable). How can I get the form to follow the model specifications?

like image 268
Neil Avatar asked Dec 10 '13 06:12

Neil


1 Answers

You actually want to set an initial value, not a default value. See the docs. Your code should be:

from django.utils import timezone


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

A default value is the value provided to an attribute if no value is set for the field. The distinction between initial and default arguments mirrors the difference between Django's initial argument for form fields and Django's default argument for model fields.

like image 136
mcastle Avatar answered Oct 13 '22 08:10

mcastle