如何处理Django API框架POST的外键和多个错误?



我有以下代码:

models.py

class Device(models.Model):
hostname = models.CharField(max_length=50, unique = True)
ipaddr = models.GenericIPAddressField(protocol='ipv4', unique=True, verbose_name='mangement IP') ##Use for mgt_id_addr
date_added = models.DateTimeField(default=timezone.now)

def __str__(self):
return self.hostname
class DeviceDetail(models.Model):

SUBNET_CHOICES = (
('16','16'),
('17', '17'),
('18','18'),
('19','19'),
('20','20'),
('21', '21'),
('22', '22'),
('23', '23'),
('24', '24'),
('25', '25'),
('26', '26'),
('27', '27'),
('28', '28'),
('29', '29'),
('30', '30'),
)
DEV_MODS =(
('Catalyst 9606R', 'Catalyst 9606R'),
('C9300L-48T-4X', 'C9300L-48T-4X')
)

mgt_interface = models.CharField(max_length=50)
subnetmask = models.CharField(max_length=2, choices = SUBNET_CHOICES)
ssh_id = models.CharField(max_length=50)
ssh_pwd = models.CharField(max_length=50)
enable_secret = models.CharField(max_length=50)
dev_mod=models.CharField(max_length=50, choices = DEV_MODS) ##device_model replacement
DD2DKEY = models.ForeignKey(Device, on_delete=models.CASCADE) ##The key to link up the tables

def __str__(self):
return self.hostname

serializers.py

from rest_framework import serializers
from .models import Device, DeviceDetail
class DeviceSerializers(serializers.ModelSerializer):
class Meta:
model=Device
fields = '__all__'
class DeviceDetailSerializers(serializers.ModelSerializer):
class Meta:
model = DeviceDetail
fields = ['mgt_interface', 'subnetmask', 'ssh_id', 'ssh_pwd', 'enable_secret', 'dev_mod']

views.py

@api_view(['POST'])
def create_device(request):
device = Device()
devicedetail = DeviceDetail()
deviceserializer = DeviceSerializers(device, data = request.data)
devdserializer = DeviceDetailSerializers(devicedetail, data = request.data)
if deviceserializer.is_valid() and devdserializer.is_valid():   
deviceserializer.save()
devdserializer.save(DD2DKEY=deviceserializer.id)                
results = {
"device":deviceserializer.data,
"device_details" : devdserializer.data,
}
return Response(results, status=status.HTTP_201_CREATED)
else:
errors = {
"device":deviceserializer.errors,
"device_details" : devdserializer.errors,
}
return Response(errors, status=status.HTTP_400_BAD_REQUEST)

这个语句devdserializer.save(DD2DKEY=deviceserializer.id)给了我这个问题。我尝试了devdserializer.save(DD2DKEY=deviceserializer)也没有解决这个问题。错误powershell所示:

ValueError: Cannot assign "DeviceSerializers(<Device: Testing10>, data=<QueryDict: {'hostname': ['Testing10'], 'ipaddr': ['10.10.10.10'], 'mgt_interface': ['1'], 'subnetmask': ['16'], 'ssh_id': ['1'], 'ssh_pwd': ['1'], 'enable_secret': ['1'], 'dev_mod': ['Catalyst 9606R']}>):
id = IntegerField(label='ID', read_only=True)
hostname = CharField(max_length=50, validators=[<UniqueValidator(queryset=Device.objects.all())>])
ipaddr = IPAddressField(label='Mangement IP', validators=[<function validate_ipv4_address>, <UniqueValidator(queryset=Device.objects.all())>])
date_added = DateTimeField(required=False)": "DeviceDetail.DD2DKEY" must be a "Device" instance.

我面临的另一个问题是错误,我不知道为什么,但powershell的输出显示以下错误,当我已经在if语句中调用is.valid()的函数:

AssertionError: You must call `.is_valid()` before accessing `.errors`.

必须传递Device instance而不是Device serializer instance:所以这部分代码是错误的

deviceserializer.save()
devdserializer.save(DD2DKEY=deviceserializer.id)

改为

device_instance = deviceserializer.save()
devdserializer.save(DD2DKEY=device_instance)

序列化器.save()为您返回模型实例,并且可以使用它。

最新更新