我的 models.py 看起来像这样:
class IP(models.Model):
hostname = models.CharField(max_length=50, unique=True)
ip_address = models.CharField(unique=True)
class IPGroup(models.Model):
name = model.CharField(max_length=50, unique=True)
ips = models.ManyToManyField(IP, through=IPGroupToIP)
class IPGroupToIP(models.Model):
ip_group = models.ForeignKey(IPGroup)
ip = models.ForeignKey(IP)
我的 serializers.py 看起来像这样:
class IPSerializer(serializers.ModelSerializer):
class Meta:
model = IP
fields = ['id', 'host_name', 'ip_address']
class IPGroupSerializer(serializers.ModelSerializer):
ips = IPSerializer(many=True)
class Meta:
model = IPGroup
depth = 1
fields = '__all__'
def create(self, validated_data):
# Pop out ips since these are M2M relations and have to be created separately
ips_data = validated_data.pop('ips', None)
# Create the IPGroup object
ip_group_obj = IPGroup.objects.create(name=validated_data['name'])
if ips_data:
for ip in ips_data:
# Get the ip object id if already created or create it on the fly and save it
ip_obj, created = IP.objects.get_or_create(host_name=ip['host_name'], ip_address=ip['ip_address'])
# Update through table for M2M relationship
IPGroupToIP.objects.create(ip_group_id=ip_group_obj.id, ip_id=ip_obj.id)
return ip_group_obj
最后是我的 views.py 如下:
class IPGroupCreateView(generics.CreateAPIView):
queryset = IPGroup.objects.get_queryset()
serializer_class = IPGroupSerializer
这可以按预期工作,并且将以下JSON创建请求发送到API端点即可完成工作:
{
"name":"TestIPGroup1",
"ips": [{"name":"host1","value":"8.8.4.4"}, {"name":"host2","value":"8.8.8.8"}]
}
但是,如果我发送另一个具有相同IP地址的JSON创建请求,如下所示:
{
"name":"TestIPGroup2",
"ips": [{"name":"host1","value":"8.8.4.4"}, {"name":"host2","value":"8.8.8.8"}]
}
它给我一个错误,指出 IP地址已经存在。现在正在发生这种情况,因为嵌套IPSerializer的IP字段 unique 验证检查开始了。如何禁用默认字段唯一检查?我的DRF版本是3.8.2
编辑
我尝试覆盖以下方法,但似乎不起作用:
class IPGroupSerializer(serializers.ModelSerializer):
ips = IPSerializer(many=True)
class Meta:
model = IPGroup
depth = 1
fields = '__all__'
def run_validators(self, value):
for validator in self.validators:
if isinstance(validator, validators.UniqueValidator):
self.validators.remove(validator)
super(IPGroupSerializer, self).run_validators(value)
答案 0 :(得分:1)
显式指定id
字段,并将empty
验证者添加为
class IPSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(validators=[])
class Meta:
model = IP
fields = ['id', 'host_name', 'ip_address']
更新
class IPSerializer(serializers.ModelSerializer):
class Meta:
model = IP
fields = ['id', 'host_name', 'ip_address']
def __init__(self, *args, **kwargs):
nested = kwargs.pop('nested', False)
super().__init__(*args, **kwargs)
if nested:
self.fields.update(
{"id": serializers.IntegerField(validators=[])}
)
class IPGroupSerializer(serializers.ModelSerializer):
ips = IPSerializer(many=True, nested=True)
# Your code