Luctia
Luctia

Reputation: 376

DRF custom serializer "Field name is not valid for model"

I have a big model that I'd like to reduce to just a name and its ID. My (relevant) code is as follows:

### Models
class Person(models.Model):
    first_name = models.CharField(max_length=80)
    last_name = models.CharField(max_length=80)

class Employee(models.Model):
    person = models.OneToOneField('Person', related_name='employee', on_delete=models.CASCADE)

class Job(models.Model):
    employee = models.ForeignKey('Employee')

### Serializers
class SimpleEmployeeSerializer(serializers.ModelSerializer):
    def to_representation(self, instance):
        name = instance.person.first_name + ' ' + instance.person.last_name
        return {
            'id': instance.id,
            'name': name,
        }

    def to_internal_value(self, data):
        try:
            try:
                obj_id = data['id']
                return Employee.objects.get(id=obj_id)
            except KeyError:
                raise serializers.ValidationError(
                    'id is a required field.'
                )
            except ValueError:
                raise serializers.ValidationError(
                    'id must be an integer.'
                )
        except Employee.DoesNotExist:
            raise serializers.ValidationError(
                'Obj does not exist.'
            )

    class Meta:
        model = Employee
        fields = ['id', 'name']

class JobSerializer(WritableNestedModelSerializer):
    employee = SimpleEmployeeSerializer(many=False)

    class Meta:
        model = MpProject
        fields = [
            'id',
            'employee',
        ]

Please do not concern yourself with whether this should or should not be a OneToOne relation, my model is more complicated in practice.

The error I'm getting is ImproperlyConfigured: Field name 'name' is not valid for model 'Employee'. I didn't get this error when I had not implemented to_internal_value, but I need this since I want to be able to POST a new Job with the SimpleEmployee format. Can someone tell me why I'm getting this error?

Upvotes: 2

Views: 4783

Answers (1)

Felix Eklöf
Felix Eklöf

Reputation: 3720

It's because of fields

class Meta:
    model = Employee
    fields = ['id', 'name'] # <- this line

You might be able to fix this by adding a field:

class SimpleEmployeeSerializer(serializers.ModelSerializer):
    name = serializers.CharField(required=False) # Maybe add read_only or write_only depending on usage.

Upvotes: 5

Related Questions