Django остальные рамки поста в дб - PullRequest
0 голосов
/ 12 января 2020

Я работаю над своим школьным проектом, и я полностью застрял. Я новичок ie на django. Попытка создать Nmap Reporter 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 ().

1 Ответ

0 голосов
/ 12 января 2020

В ServiceSerializer изменить vulnerabilities с MethodField на:

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

и удалить get_vulnerabilities метод.

Это сработало для меня.

...