调用create()时出现`TypeError`。您可能需要将该字段设置为只读,或覆盖create()方法

时间:2017-06-23 08:58:17

标签: django django-rest-framework

不确定这里发生了什么。我正在尝试通过Django-rest-framework创建一个新实例。 我做错了什么?

有一些只读字段被提交回来。 我尝试在序列化程序中通过read_only_fields将它们标记为只读,并在模型的字段中将它们指定为editable=False

注意:如果可能,我宁愿避免指定自己的create方法。这应该通过标记的here

标准功能来实现 发布以下内容时

{
  "displayName": "New test",
  "backgroundColour": "#4d3567",
  "foregroundColour": "#FFFFFF",
  "helpText": "test",
  "description": "test",
  "comment": "test."
}

我得到了:

TypeError at /api/v1/classifications/
Got a `TypeError` when calling `ClassificationLabel.objects.create()`. This may be because you have a writable field on the serializer class that is not a valid argument to `ClassificationLabel.objects.create()`. You may need to make the field read-only, or override the ClassificationLabelListSerializer.create() method to handle this correctly.

models.py

class ClassificationLabel(models.Model):
    """
    this model is used to create all instances of classifications 
    labels that will be displayed to a user
    """
    displayName = models.CharField('Classification label display name', max_length = 32)
    helpText = models.TextField('Explanatory text about this label', max_length = 140, blank=True)
    backgroundColour = models.CharField('Hex code for background colour including Alpha', max_length=8)
    foregroundColour = models.CharField('Hex code for foreground colour include Alpha', max_length=8)
    description = models.TextField('Description of this label', max_length = 256, blank=True)
    comment = models.TextField('Internal comments for this label', max_length = 1024, blank=True)
    lastChanged = models.DateTimeField('last changed timestamp', auto_now=True, editable=False)
    identifier = models.CharField('Classification label ID', max_length = 128, blank=True, editable=False)
    revision = models.PositiveIntegerField('Revision number for this label', default=1, editable=False)
    #placeholder for lastChangedBy

    def clean(self):
        #the following code generates a unique identifier and checks it for collisions against existing identifiers
        if not self.identifier:
            stringCheck = False
            while stringCheck is False:
                newString = str(uuid.uuid4())
                newString.replace('-', '')
                doesStringExist = ClassificationLabel.objects.filter(identifier=newString).count()
                if doesStringExist == 0:
                    stringCheck = True
            self.identifier = newString

    def __str__(self):
        return self.displayName + " - " + self.identifier

    def save(self, force_insert=False, force_update=False):
        self.revision += 1
        super(ClassificationLabel, self).save(force_insert, force_update) # Call the "real" save() method.

串行器:

class ClassificationLabelListSerializer(serializers.ModelSerializer):
    class Meta:
        model = ClassificationLabel
        fields = ('displayName', 'helpText', 'identifier', 'backgroundColour', 'foregroundColour', 'comment', 'description', 'lastChanged', 'revision')
        #read_only_fields = ('identifier', 'lastChanged', 'revision',)

views.py

class ClassificationLabelList(mixins.ListModelMixin,generics.GenericAPIView, mixins.CreateModelMixin):
queryset = ClassificationLabel.objects.all()
serializer_class = ClassificationLabelListSerializer

def get(self, request, *args, **kwargs):
    return self.list(request, *args, **kwargs)

def post(self, request, *args, **kwargs):
    return self.create(request, *args, **kwargs)

似乎修复了什么 一个更新的save()方法似乎修复了这个问题。更新的代码如下:

    def save(self, *args, **kwargs):
        self.revision += 1
        super(ClassificationLabel, self).save() # Call the "real" save() method.

1 个答案:

答案 0 :(得分:1)

也许在序列化程序中尝试这样的事情,

class ClassificationLabelListSerializer(serializers.ModelSerializer):
    lastChanged = serializers.DateTimeField(read_only=True)
    identifier = serializers.CharField(read_only=True)
    revision = serializers.IntegerField(read_only=True)
    class Meta:
        model = ClassificationLabel
        fields = ('displayName', 'helpText', 'identifier', 'backgroundColour', 'foregroundColour', 'comment', 'description', 'lastChanged', 'revision')

    def create(self, validated_data):
        return ClassificationLabel.objects.create(**validated_data)

另外,在models.py,

中编辑save方法
def save(self, *args, **kwargs):
    self.revision += 1
    return super(ClassificationLabel, self).save(*args, **kwargs) #