У меня есть три связанных модели, и мне нужно сохранить все экземпляры в одной транзакции.
Упрощенная версия моих моделей:
class Recibosventas(models.Model):
idreciboventa = models.AutoField(primary_key=True)
idemplea = models.ForeignKey(Empleados, models.DO_NOTHING, db_column='idemplea', blank=True, null=True)
idempres = models.SmallIntegerField()
categocompro = models.CharField(max_length=2)
tipocompro = models.CharField(max_length=1)
puntoventa = models.SmallIntegerField()
numero = models.IntegerField(blank=True, null=True)
class Meta:
managed = True
db_table = 'recibosventas'
unique_together = (('idempres', 'categocompro', 'tipocompro', 'puntoventa', 'numero'),)
class Fondos(models.Model):
idfondo = models.AutoField(primary_key=True)
idemplea = models.ForeignKey(Empleados, models.DO_NOTHING, db_column='idemplea', blank=True, null=True)
idtipofondo = models.ForeignKey('Tiposfondo', models.DO_NOTHING, db_column='idtipofondo')
idconcepfondo = models.ForeignKey(Conceptosfondos, models.DO_NOTHING, db_column='idconcepfondo')
idreciboventa = models.ForeignKey('Recibosventas', models.DO_NOTHING, db_column='idreciboventa', related_name='fondoreciboventa', blank=True, null=True)
class Meta:
managed = True
db_table = 'fondos'
class Movimientosfondos(models.Model):
idmovimifondo = models.AutoField(primary_key=True)
idfondo = models.ForeignKey(Fondos, models.DO_NOTHING, db_column='idfondo', related_name='movimientosfondos', blank=True, null=True)
iddispon = models.ForeignKey(Disponibilidades, models.DO_NOTHING, db_column='iddispon')
class Meta:
managed = True
db_table = 'movimientosfondos'
serializers.py:
class MovimientosfondosSerializer(serializers.ModelSerializer):
class Meta:
model = Movimientosfondos
fields='__all__'
class FondosSerializer(serializers.ModelSerializer):
movimientosfondos = MovimientosfondosSerializer(many=True)
class Meta:
model = Fondos
fields='__all__'
def create(self, validated_data):
with transaction.atomic():
# Crear la instancia de pedidos de venta
movimientosfondos_data = validated_data.pop('movimientosfondos')
fondos = Fondos.objects.create(**validated_data)
# crear cada instancia de movimientosfondos
for movimientosfondos_data in movimientosfondos_data:
movimientosfondos_data['idfondo'] = fondos
Movimientosfondos.objects.create(**movimientosfondos_data)
return fondos
def update(self, instance, validated_data):
with transaction.atomic():
# Crear la instancia de pedidos de venta
movimientosfondos_data = validated_data.pop('movimientosfondos')
# Eliminar el detalle de ventas
for movimientosfondos in (instance.movimientosfondos).all():
movimientosfondos.delete()
# crear nuevamente cada instancia de ventasarticulos
for movimientosfondos_data in movimientosfondos_data:
movimientosfondos_data['idfondo'] = instance
Movimientosfondos.objects.create(**movimientosfondos_data)
return instance
class RecibosventasSerializer(serializers.ModelSerializer):
fondoreciboventa = FondosSerializer(many=True)
class Meta:
model = Recibosventas
fields='__all__'
def create(self, validated_data):
with transaction.atomic():
# Crear la instancia de pedidos de venta
fondosreciboventa_data = validated_data.pop('fondoreciboventa')
recibosventas = Recibosventas.objects.create(**validated_data)
# crear cada instancia de fondos
for fondoreciboventa_data in fondosreciboventa_data:
fondoreciboventa_data['idreciboventa'] = recibosventas
Fondos.objects.create(**fondoreciboventa_data)
return recibosventas
def update(self, instance, validated_data):
with transaction.atomic():
# Crear la instancia de pedidos de venta
fondosreciboventa_data = validated_data.pop('fondoreciboventa')
for fondoreciboventa in (instance.fondoreciboventa).all():
fondoreciboventa.delete()
# crear nuevamente cada instancia de pedidoventasarticulos
for fondoreciboventa_data in fondosreciboventa_data:
fondoreciboventa_data['idreciboventa'] = instance
Fondos.objects.create(**fondoreciboventa_data)
return instance
apiviews:
class FondosList(generics.ListCreateAPIView):
queryset = Fondos.objects.all()
serializer_class = FondosSerializer
def perform_create(self, serializer):
idemplea = Empleados.objects.get(usuariweb = self.request.user)
serializer.save(idemplea=idemplea)
class RecibosventasList(generics.ListCreateAPIView):
queryset = Recibosventas.objects.all()
serializer_class = RecibosventasSerializer
def perform_create(self, serializer):
idemplea = Empleados.objects.get(usuariweb = self.request.user)
serializer.save(idemplea=idemplea)
class RecibosventasDetalle(generics.RetrieveDestroyAPIView):
queryset = Recibosventas.objects.all()
serializer_class = RecibosventasSerializer
def perform_destroy(self, instance):
with transaction.atomic():
# Eliminar el detalle de pedidosventas
for movimientosfondos in (instance.fondoreciboventa.movimientosfondos).all():
movimientosfondos.delete()
instance.fondoreciboventa.delete()
# Eliminar el encabezado pedidosventas
instance.delete()
class RecibosventasUpdate(generics.UpdateAPIView):
queryset = Recibosventas.objects.all()
serializer_class = RecibosventasSerializer
urls:
urlpatterns = [
path('v1/recibosventas/', RecibosventasList.as_view(), name='recibosventas_list'),
path('v1/recibosventas/<int:pk>', RecibosventasDetalle.as_view(), name='recibosventas_detalle'),
path('v1/recibosventasupdate/<int:pk>', RecibosventasUpdate.as_view(), name='recibosventas_update'),
]
Я отправляю на API:
{
"idreciboventa": null,
"idemplea" : 1,
"fondoreciboventa": [
{
"idfondo": 1,
"idemplea" : 1,
"movimientosfondos": [
{
"idmovimifondo": 1,
"idfondo": 1,
"iddispon": 9,
}
],
"idtipofondo": 1,
"idconcepfondo": 2,
}
]
"categocompro": "RC",
"tipocompro" : "F",
"puntoventa": 1,
"numero" : 1,
}
Я получаю следующую ошибку:
Прямое назначение обратной стороне связанного набора запрещено. Вместо этого используйте movimientosfondos.set ().
Я не понимаю, что я делаю неправильно. Кто-нибудь может мне помочь, пожалуйста?