Django REST框架:可浏览API表单中的默认字段

Django REST框架:可浏览API表单中的默认字段,django,django-rest-framework,Django,Django Rest Framework,我有一个模型: 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

我有一个模型:

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)
以及该模型的序列化程序:

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'
下面是列表视图:

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)
CallList
的可浏览API中,我在底部的POST表单中看到了以下内容:


我的问题是:为什么在上没有为
send\u设置默认值,而为
backup\u调用设置了一个默认值?我假设表单将遵循
XCall
模型规范,并使用
datetime.now()
作为前者的默认值,并将
backup\u调用保留为空(因为它可以为空)。如何使表单符合模型规范?

表单中的模型默认值和初始值之间存在区别。对于实际为函数的默认值尤其如此,因为只有在保存实例时才会调用它们。例如,您想使用哪个“<代码>现在/代码>——此时显示空白表单,还是用户按下“POST”的时间?如果缺少字段值,Django将在保存模型时应用默认值。要实现所需功能,需要在serialize字段中手动设置默认值,例如:

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

实际上,您需要设置一个
初始值,而不是默认值。看。您的代码应该是:

from django.utils import timezone


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

如果没有为字段设置值,则默认值是提供给属性的值。
initial
default
参数之间的区别反映了Django用于表单字段的
initial
参数和Django用于模型字段的
default
参数之间的区别。

我不确定是否看到了您描述的行为。当我尝试在未填写send_的情况下发布时,我会收到一个验证错误“此字段是必需的”。如果您说Django在保存时应用默认值,为什么会出现验证错误?其他一些信息:1)我在Django 1.6上;我模模糊糊地记得,在我从1.4升级之前,所有这些工作方式都不同。2) 奇怪的是,我在Django开发模式中看到了默认表单值,但在我的生产环境(Django+Apache+mod_wsgi)中没有看到。而且,这个答案也没有解释为什么我在
backup_calls
字段中看到了默认值。我没有在
CallSerializer
IIRC中显式设置它,字段验证首先发生在表单中。表单看到没有在send_on中输入任何内容,这是必需的,并且根据表单字段没有默认值,因此它在进入模型之前引发异常。我不知道为什么它在生产中会有不同的工作方式-听起来可能是一些奇怪的缓存问题。我怀疑,因为
backup\u calls
是一个整数字段,所以它使用的是一个为整数格式化的文本框,默认值为零。您可以通过检查html来看到这一点。该字段设置为空白和null的事实使它看起来像一个bug。这就是不同行为的原因。那么2.3.6是否有副作用,使其尊重模型默认值?您解决过这个问题吗?我现在遇到了。