【问题标题】:Django rest framework post item to dbDjango rest框架将项目发布到数据库
【发布时间】:2020-01-12 09:29:32
【问题描述】:

我正在做我的学校项目,但我完全陷入了困境。我是 django 的新手。试图创建一个 nmap 报告器 api。我有一个带有嵌套对象的 JSON 数据。我需要将此 JSON 数据保存到我的数据库中。但我不能。我的数据是这样的:

[
    {
        "host": "192.168.1.8",
        "hostname": "",
        "hostname_type": "",
        "state": "open",
        "service": [
            {
                "name": "http",
                "port": "80",
                "product": "Apache httpd",
                "version": "2.2.8",
                "extrainfo": "(Ubuntu) DAV/2",
                "vulnerabilities": [
                    {"name":"CVE Example","version":"2.42"},
                    {"name":"CVE Example","version":"2.42"},
                    {"name":"CVE Example","version":"2.42"},
                ]
            }
        ]
    }
]

但我保存的数据是:

        [
    {
        "host": "192.168.1.8",
        "hostname": "",
        "hostname_type": "",
        "state": "open",
        "service": [
            {
                "name": "http",
                "port": "80",
                "product": "Apache httpd",
                "version": "2.2.8",
                "extrainfo": "(Ubuntu) DAV/2",
                "vulnerabilities": []
            }
        ]
    }
]

谁能帮助我?谢谢。 我的模型和序列化器:

为此我有 3 个模型。

class Service(models.Model):
class Meta:
    db_table = 'tblService'

result = models.ForeignKey(Result, on_delete=models.CASCADE, related_name='service')
name = models.CharField(max_length=50, blank=True)
port = models.CharField(max_length=50, blank=True)
product = models.CharField(max_length=50, blank=True)
version = models.CharField(max_length=50, blank=True)
extrainfo = models.CharField(max_length=50, blank=True)

这是 JSON 上服务部分的服务模型。

class Vulnerability(models.Model):
class Meta:
    db_table = 'tblVulnerability'
Service = models.ForeignKey(Service, on_delete=models.CASCADE, related_name="vulnerabilities")
name = models.CharField(max_length=255)
priority = models.CharField(max_length=255)
version = models.CharField(max_length=255)
url = models.TextField()

此模型用于漏洞部分。

class Result(models.Model):
host = models.CharField(max_length=50,blank=True)
hostname = models.CharField(max_length=50,blank=True)
hostname_type = models.CharField(max_length=50,blank=True)
state = models.CharField(max_length=50,blank=True) 

这个模型是我的父模型。

还有我的序列化器:

class ScanPostSerializer(serializers.ModelSerializer):
service = ServiceSerializer(many=True)

class Meta:
    model = Result
    fields = ['host', 'hostname', 'hostname_type', 'state', 'service']

def create(self, validated_data):
    service_data = validated_data.pop('service')
    result = Result.objects.create(**validated_data)
    for servic_data in service_data:
        Service.objects.create(result=result, **servic_data)
    return result


class VulnerabilitySerializer(serializers.ModelSerializer):
class Meta:
    model = models.Vulnerability
    fields = ['pk','name', 'priority', 'version', 'url']


class ServiceSerializer(serializers.ModelSerializer):
vulnerabilities = serializers.SerializerMethodField()

class Meta:
    model = models.Service
    fields = ['name', 'port', 'product', 'version', 'extrainfo', 'vulnerabilities']

def create(self, validated_data):
    vulnerability_data = validated_data.pop('vulnerabilities')
    service = models.Service.objects.create(**validated_data)
    for vul_data in vulnerability_data:
        Vulnerability.objects.create(Service=service, **vul_data)
    return service

def get_vulnerabilities(self,obj):
    qset = Vulnerability.objects.all()
    return [VulnerabilitySerializer(m).data for m in qset]

编辑:我更改了代码中的某些部分。现在我得到了错误。

禁止直接分配到相关集的反面。改用漏洞.set()。

【问题讨论】:

  • 似乎 这是空的。可以查一下吗?
  • 我检查并更改了一些内容。现在我得到了错误。我编辑了我的答案你可以检查吗? @engin_ipek
  • 现在看来 pop 不起作用了。你能打印出验证数据并在评论中分享吗
  • 顺便说一句,为什么漏洞模型中的服务字段以大写字母开头?按照惯例,它应该以小写字母开头
  • 哦,谢谢你的建议。我改变了它。验证数据的结果稍长评论pastebin.com/BvVehqCB我上传到pastebin。

标签: python django django-rest-framework nested


【解决方案1】:

ServiceSerializer 中将 vulnerabilitiesMethodField 更改为:

class ServiceSerializer(serializers.ModelSerializer):
    vulnerabilities = VulnerabilitySerializer(many=True)

并删除get_vulnerabilities 方法。

这对我有用。

【讨论】:

  • 无效:(我做了这个更改并得到了同样的错误。所以我删除了foreign_key的related_name。现在我得到了新的错误说-> TypeError: Service() got an unexpected关键字参数“漏洞”
猜你喜欢
  • 1970-01-01
  • 2017-12-25
  • 2017-12-31
  • 2014-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多