【问题标题】:DRF custom serializer "Field name is not valid for model"DRF 自定义序列化程序“字段名称对模型无效”
【发布时间】:2021-05-10 18:49:53
【问题描述】:

我有一个大模型,我想简化为一个名称和它的 ID。我的(相关)代码如下:

### 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',
        ]

请不要担心这是否应该是 OneToOne 关系,我的模型在实践中更复杂。

我得到的错误是ImproperlyConfigured: Field name 'name' is not valid for model 'Employee'. 当我没有实现to_internal_value 时我没有得到这个错误,但我需要这个,因为我希望能够使用@987654325 发布一个新的Job @ 格式。谁能告诉我为什么会出现这个错误?

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

    因为fields

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

    您也许可以通过添加一个字段来解决此问题:

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

    【讨论】:

    • 谢谢!这解决了我最初的错误,但现在我又遇到了一个错误……你碰巧知道如何修复那个错误吗?它在网址/jobs/ 上,错误是TypeError: 'Employee' object is not a mapping
    • 顺便说一句,如果您设置 serializers.CharField(required=False) 并且序列化类型与存储在 DB 中的数据类型不匹配,它不会呈现,但它也不会抱怨。所以要小心。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-12
    • 1970-01-01
    • 2017-02-04
    • 1970-01-01
    • 2019-01-17
    • 1970-01-01
    相关资源
    最近更新 更多