使用 Django Rest Framework 序列化器创建外键关系的方法

我的模型是这样的:


class FirewallPolicy(models.Model):

    name = models.CharField(max_length=100, unique=True)

    team = models.ForeignKey(Team)

    source_ip = models.ForeignKey(IP)

    destination_ip = models.ForeignKey(IP)

现在,为了创建新的防火墙策略,应该已经有一个现有团队、source_ip 和 destination_ip。我创建新防火墙策略的负载如下:


{"name": "test-create-policy-911",

 "team": "avengers",

 "source_ip": "1.1.1.1",

 "destination_ip": "2.2.2.2",

}

我创建新防火墙策略的序列化程序如下:


class FirewallPolicyCreateSerializer(serializers.ModelSerializer):

    name = serializers.CharField(max_length=100)

    team = serializers.CharField(max_length=100)

    source_ip = serializers.CharField(max_length=100)

    destination_ip = serializers.CharField(max_length=100)


    class Meta:

        model = Policy

        fields = ['id', 'name', 'team', 'source_ip', 'destination_ip']


    def validate(self, data):

        try:

            Team.objects.get(name=data['team'])

            IP.objects.get(name=data['source_ip'])

            IP.objects.get(name=data['destination_ip'])

        except ObjectDoesNotExist:

            raise serializers.ValidationError("Entities must exist before you can associate it with a Firewall Policy")


    def create(self, validated_data):

        team = Team.objects.get(name=validated_data['team'])

        source_ip = IP.objects.get(name=validated_data['source_ip'])

        destination_ip = IP.objects.get(name=validated_data['destination_ip'])

        policy  = Policy.objects.create(name=validated_data['name'], 

                                        team_id=team.id, 

                                        source_ip_id = source_ip.id, 

                                        destination_ip_id = destination_ip.id )

        return policy 

我不确定这是否是向模型添加外键的正确方法,因为它看起来工作量太大。在序列化程序可以自动检查所有这些并添加外键的地方,我是否遗漏了什么?


小唯快跑啊
浏览 265回答 1
1回答

扬帆大鱼

是的,你做的工作比你需要的多得多。您应该使用SlugRelatedField定义您的字段,以允许 DRF 从相关模型上的字段自动填充它们。所以:class FirewallPolicyCreateSerializer(serializers.ModelSerializer):    team = serializers.SlugRelatedField(queryset=Team.objects.all(), slug_field='name')    source_ip = serializers.SlugRelatedField(queryset=IP.objects.all(), slug_field='source_ip')    destination_ip = serializers.SlugRelatedField(queryset=IP.objects.all(), slug_field='destination_ip')    class Meta:        model = Policy        fields = ['id', 'name', 'team', 'source_ip', 'destination_ip']现在您不需要定义validate或根本不需要定义create,因为 DRF 将完成所有相关的验证和分配。(请注意,您也不需要重新定义该name字段,因为您不会更改底层模型字段的任何内容。)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python