Сохранение объекта JSON как всей модели в DJANGO
Я хочу сохранить информацию, которую мне посылает фронт в базу данных (я получаю JSON), проблема в том, что в модели есть внешние ключи и они могут быть заполнены или не заполнены и когда я пытаюсь сохранить некоторые данные с пустым FK я получаю ошибку 'matching' query does not exist.' или другие ошибки, связанные с тем, что 'key' не существует в базе данных. Что мне приходит в голову, так это удалить его из фронта перед отправкой в DJANGO и сохранить объект как таковой, но я не знаю, возможно ли это, если у вас есть другое решение, я буду очень признателен
Добавить
def agregarIniciativa(request):
if request.user.is_authenticated:
if request.method =='POST':
try:
data = json.load(request)
iniciativa = Iniciativa(
iniciativa = data['nombre'],
fecha_inicio = data['fecha_inicio'],
fecha_final = data['fecha_final'],
canal=Canales.objects.get(id=int(data['canal'])),
territorio = data['territorios'],
audiencia = AudienciaDirigida.objects.get(id=int(data['audiencia'])),
bigbet = BigBet.objects.get(id=int(data['bigBet'])),
marca = Marcas.objects.get(id=int(data['marca'])),
fgp = float(data['fgp']),
objetivo = data['objetivo'],
call2action = data['call2Action'],
dialogo_valor = data['dialogoValor'],
cobertura = data['cobertura'],
volumen_datos = data['volumen'],
kpi_medicion = data['kpi'],
inversion_datos = data['inversion'],
beneficio_datos = data['beneficio'],
volumen_total = int(data['total_vol']),
inversion_total = int(data['total_inv']),
beneficio_total = int(data['total_ben']),
marcas = data['marcas'],
fgp_datos = data['fgpDatos']
)
iniciativa.save()
return JsonResponse({
"msg": "Guardado"
})
except Exception as e:
print('Error: Agregar iniciativa')
print(str(e))
return HttpResponseBadRequest('Error al agregar iniciativa.', format(request.method), status=400)
else:
return HttpResponseBadRequest('Favor de ingresar sesión en el sistema.', format(request.method), status=401)
Model.py
class Iniciativa(models.Model):
iniciativa = models.CharField(max_length=150)
fecha_inicio = models.DateField(blank=True, null=True)
fecha_final = models.DateField(blank=True, null=True)
canal = models.ForeignKey(Canales, blank=True, null=True, on_delete=models.CASCADE)
territorio = models.JSONField(default=dict, blank=True, null=True)
audiencia = models.ForeignKey(AudienciaDirigida, blank=True, null=True, on_delete=models.CASCADE)
bigbet = models.ForeignKey(BigBet, blank=True, null=True, on_delete=models.CASCADE)
marca = models.ForeignKey(Marcas, blank=True, null=True, on_delete=models.CASCADE)
fgp = models.FloatField(blank=True, null=True)
objetivo = models.TextField(blank=True, null=True)
call2action = models.TextField(blank=True, null=True)
dialogo_valor = models.TextField(blank=True, null=True)
cobertura = models.TextField(blank=True, null=True)
kpi_medicion = models.TextField(blank=True, null=True)
volumen_datos = models.JSONField(default=dict, blank=True, null=True)
inversion_datos = models.JSONField(default=dict, blank=True, null=True)
beneficio_datos = models.JSONField(default=dict, blank=True, null=True)
avance_captura = models.IntegerField(default=0)
observaciones = models.IntegerField(default=0)
observaciones_solventadas = models.IntegerField(default=0)
aprobada = models.BooleanField(default=False)
ranking = models.IntegerField(default=0)
ranking_temp = models.IntegerField(default=0)
volumen_total = models.DecimalField(max_digits=30, decimal_places=15, default=0.0, null=True)
inversion_total = models.DecimalField(max_digits=30, decimal_places=15, default=0.0, null=True)
beneficio_total = models.DecimalField(max_digits=30, decimal_places=15, default=0.0, null=True)
fgp_datos = models.JSONField(default=dict, blank=True, null=True)
marcas = models.JSONField(default=dict, blank=True, null=True)
estatus = models.IntegerField(choices=ESTATUS,default=0)
class Meta:
verbose_name='Iniciativa'
verbose_name_plural='Iniciativas'
ordering=('id',)
def __str__(self) -> str:
return self.iniciativa
Проблема в том, что ваш метод canal=Canales.objects.get(id=int(data['canal'])),
get вызовет исключение, когда не найдет объект. Но вы смиритесь с этим, поскольку вы позволяете canal
быть Null
в вашей модели. Поэтому просто используйте вспомогательную функцию, подобную этой:
def get_if_exists(model, **kwargs):
try:
obj = model.objects.get(**kwargs)
except model.DoesNotExist:
obj = None
return obj
Это вернет None
, если объект не существует, так что вы можете сделать
canal = get_if_exists(Canales, id=int(data['canal']))
И аналогично везде, где вы используете get()