用pk以外的属性标识Django Rest Framework ModelSerializer ForeignKey

时间:2018-11-14 05:05:27

标签: django django-rest-framework

我觉得这是一个非常基本的问题,但在DRF文档中找不到答案。

假设我有一个models.py设置,如下:

#models.py
class Person(models.Model):
    name = models.CharField(max_length=20)
    address = models.CharField(max_length=20)

class House(models.Model):
    name = models.CharField(max_length=20)
    owner = models.ForeignKey(Person)

我有一个像这样设置的ModelSerializer:

#serializers.py
class House(serializers.ModelSerializer):
    class Meta:
        model = House
        fields = '__all__'

我想做的是能够POST新建房屋对象,但不必提供 Person对象的pk ,我希望能够提供< strong> Person对象的名称。

例如

post = {'name': 'Blue House', 'owner': 'Timothy'}

我正在使用的实际模型有几个ForeignKey字段,所以我想知道最规范的方法。

2 个答案:

答案 0 :(得分:3)

一种解决方案可能是使用SlugRelatedField

#serializers.py
class House(serializers.ModelSerializer):
    owner = serializers.SlugRelatedField(
        slug_field="name", queryset=Person.objects.all(),
    )
    class Meta:
        model = House
        fields = '__all__'

这也会更改序列化器的表示形式,因此在渲染时将显示“人”的名称。如果需要渲染Person的主键,则可以重写House序列化器to_representation()方法,也可以通过继承SlugRelatedField并在其上覆盖to_representation()来实现小的自定义序列化器字段。

答案 1 :(得分:0)

通过覆盖 create() 方法,如下所述更改序列化器

class House(serializers.ModelSerializer):
    owner = serializers.CharField()

    class Meta:
        model = House
        fields = '__all__'

    def create(self, validated_data):
        owner = validated_data['owner']
        person_instance = Person.objects.get(owner=owner)
        return House.objects.create(owner=person_instance, **validated_data)