Python 使用Django Rest框架序列化程序创建外键关系的方法

Python 使用Django Rest框架序列化程序创建外键关系的方法,python,django,django-rest-framework,serialization,Python,Django,Django Rest Framework,Serialization,我的模型是这样的: 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) 现在,为了创建一个新的防火墙策略,应该已经有一个现有的团队,

我的模型是这样的:

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)
现在,为了创建一个新的防火墙策略,应该已经有一个现有的团队,源ip和目标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 
创建新防火墙策略的序列化程序如下所示:

{"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 

我不确定这是否是向模型添加外键的正确方法,因为这似乎太多工作了。序列化程序是否可以自动检查所有这些并添加外键?是的,您所做的工作比需要的多得多

您应该使用定义字段,以允许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将执行所有相关的验证和分配


(注意,您也不需要重新定义
名称
字段,因为您没有更改基础模型字段的任何内容。)

如何在序列化程序的
create()
字典中实现此解决方案?