`TypeError` when calling create (). You may need to make the field read-only or override the create () method
Not sure what's going on here. I am trying to create a new instance through the Django-rest-framework. What am I doing wrong?
Several read-only fields appear. I've tried marking them read-only through read_only_fields
in the serializer, and also specifying them as editable=False
within the fields of the model.
Note. I'd rather avoid specifying my own creation method if possible. This should work through the standard functionality as described here
when sending the following message:
{
"displayName": "New test",
"backgroundColour": "#4d3567",
"foregroundColour": "#FFFFFF",
"helpText": "test",
"description": "test",
"comment": "test."
}
I get:
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.
serializer:
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)
what seemed to fix it, his updated save () method seems to fix it. updated code below:
def save(self, *args, **kwargs):
self.revision += 1
super(ClassificationLabel, self).save() # Call the "real" save() method.
source to share
Maybe try something like this in your serializer,
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)
Also edit the save method in your models.py,
def save(self, *args, **kwargs):
self.revision += 1
return super(ClassificationLabel, self).save(*args, **kwargs) #
source to share