Django REST框架:使字段可选

时间:2014-04-24 16:42:25

标签: django django-rest-framework

我的用户可以使用项目创建一个或多个列表。

我正在使用django REST-framework并继承' viewsets.ModelViewSet'接收json对象list_item,其中包含foreign key:列表字段。

这是我想要做的:

  • 在用户发布他的第一个项目时自动创建新列表。目前这会产生错误,因为列表ID是必需的。
  • 发布列表ID应该是可选的(以便用户可以发布到多个列表)

Testcode(简化):

test_posting_item_creates_list(self):
    item = {
        'name': "test",
     #   'list': 1,
        'user': self.user.id,

    }
    response = self.client.post('/api/listitems/',
                        json.dumps(item),
                        content_type="application/json")
    self.assertEqual(response.status_code, 201, 'statuscode is 201 created')

这是我的序列化程序

class ItemSerializer(serializers.ModelSerializer):

    # this works for changing the list but a list field is required when posting
    def validate(self, attrs):     
        if 'list' in attrs:
             attrs['list'] = TodayList.objects.create()


    class Meta:
        model = TodayListItem
        fields =('id',
                 'name',
                 'user',
                 'list',
    )

使用我的validate方法,我可以将列表更改为另一个,所以我尝试了: if 'list' not in attrs:但这不起作用。

Serializer是"截取"的正确位置帖子并创建列表?如何使字段可选?

2 个答案:

答案 0 :(得分:0)

基于Django REST框架手册

  

字段级验证

     

您可以通过添加指定自定义字段级验证   .validate_方法到您的Serializer子类。这些是   类似于Django表单上的.clean_方法,但接受   论点略有不同。

     

他们将反序列化属性的字典作为第一个参数,   和该字典中的字段名称作为第二个参数(将   要么是字段的名称,要么是源参数的值   该字段,如果提供了一个)。

因此,解决方案是创建一个列表验证方法,如下所示:

def validate_list(self, attrs, source):
    """
    Check that the list is correct or not?
    """
    if list not in attrs:
        list_item = TodayList.objects.create()
        list = list_item.id
    return attrs

另一个解决方案是在模型级别,通过覆盖save()并检查列表ID。

def save(self, *args, **kwargs):
    if self.list is None:
        self.list = TodayList.objects.create()
    super(TodayListItem, self).save(*args, **kwargs) # Call the "real" save() method.

答案 1 :(得分:0)

在序列化程序中,您可以将required参数作为False

传递,将字段标记为不需要的字段
class UserResponse(ModelSerializer):
    response = IntegerField()
    meta_data = MetaDataSerializer(allow_null=True, required=False)