如何使用特定键获取模型对象
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用特定键获取模型对象相关的知识,希望对你有一定的参考价值。
不是发布整个Server
json,而是只发布ip
字段并从其模型中获取对象。
但是如果我发布数据,它会抱怨;如果我通过创建Server
用ServerIP = serializers.CharField()
以外的键发布,则显示AttributeError。我该如何实现?
curl -X POST --header 'Content-Type: application/json' --header 'Accept: text/plain' -d '
{
"Destination": "destination information",
"Server": "165.213.100.100"
}
' 'http://localhost:8001/api/server/registration'
{
"Server": {
"non_field_errors": [
"Invalid data. Received str instead of dictionary."
]
}
}
class Server(models.Model):
class Meta:
unique_together = ('ip',)
hostname = models.CharField(default=None, null=True, blank=True, max_length=100)
ip = models.GenericIPAddressField(default=None, null=True, blank=True)
class Registration(models.Model):
class Meta:
unique_together = ('Server', 'Destination')
Server = models.ForeignKey(Server, default=None, blank=True,
null=True, on_delete=models.SET_NULL, related_name='firewall_server')
Destination = models.CharField(default=None, blank=True, null=True, max_length=100)
class RegistrationView(ListCreateAPIView):
serializer_class = RegistrationSerializer
queryset = Registration.objects.all()
def get_serializer(self, *args, **kwargs):
if self.request.method.lower() == 'post':
data = kwargs.get('data')
kwargs['many'] = isinstance(data, list)
return super(RegistrationView, self).get_serializer(*args, **kwargs)
def perform_create(self, serializer):
return serializer.save()
class RegistrationSerializer(serializers.ModelSerializer):
class Meta:
model = Registration
fields = '__all__'
validators = []
Server = ServerSerializer(read_only=False, many=False, required=False)
def create(self, validated_data):
destination = validated_data.pop('Destination')
server_ip = validated_data.pop('Server') # <<= Here. It can't parse string.
server = Server.objects.get(ip=server_ip)
serialized, _ = Registration.objects.update_or_create(
Type=security_type, Server=server, Destination=destination,
defaults=validated_data)
return serialized
答案
由于使用的是嵌套序列化器,因此DRF在反序列化过程中期望使用类似字典的对象。
class RegistrationSerializer(serializers.ModelSerializer):
# other piece of code
Server = serializers.CharField()
def to_representation(self, instance):
rep = super().to_representation(instance)
rep['Server'] = ServerSerializer(instance.Server).data
return rep
参考: DRF: Simple foreign key assignment with nested serializers?
以上是关于如何使用特定键获取模型对象的主要内容,如果未能解决你的问题,请参考以下文章