如何使用特定键获取模型对象

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用特定键获取模型对象相关的知识,希望对你有一定的参考价值。

不是发布整个Server json,而是只发布ip字段并从其模型中获取对象。

但是如果我发布数据,它会抱怨;如果我通过创建ServerServerIP = 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?

以上是关于如何使用特定键获取模型对象的主要内容,如果未能解决你的问题,请参考以下文章

如何对对象中特定键的所有值求和?

使用特定对象而不是对象属性获取核心数据

如何使用猫鼬获取文档的特定键值

Django ORM:如何根据所有记录中的列获取唯一记录(需要模型对象而不是特定值对象)

无法在 JSON-SERVER 中获取对象键数据

如何使用 Django 中另一个模型的主键获取条目?