0

I've got these models, and I want to fill an instance of Reporte after it gets saved certain data related to the dates. In the post_save it access the sales made between the dates passed and then it adds them to manytomany field in Reporte but I can't save them to a Reporte instance and I don't understand why

class Venta(models.Model):
    repuesto = models.ForeignKey(Repuestos, models.CASCADE)
    cantidad = models.IntegerField()
    fecha_venta = models.DateField()
    total = models.FloatField(null=True, blank=True)

    def __str__(self):
        return f'{self.repuesto} - {self.cantidad} - {self.fecha_venta}'

class Reporte(models.Model):
    fecha_inicio = models.DateField()
    fecha_fin = models.DateField()
    ventas = models.ManyToManyField(Venta, null=True, blank=True)
    estado_de_cuenta = models.FloatField(null=True, blank=True)
    costo_de_inventario = models.FloatField(null=True, blank=True)
    deficit_de_productos = models.CharField(max_length=100, null=True, blank=True)
@receiver(post_save, sender=Reporte)
def guarda_venta(sender, instance, created, **kwargs):
    if created:
        vent = Venta.objects.all()
        ventas_delta = vent.filter(fecha_venta__range=[instance.fecha_inicio, instance.fecha_fin])
        instance.ventas.set(ventas_delta)
        instance.save()

Anyone knows what am I doing wrong?

2 Answers2

1

Instead of .save() you should use .add()

ex:

@receiver(post_save, sender=Reporte)
def guarda_venta(sender, instance, created, **kwargs):
    if created:
        vent = Venta.objects.all()
        ventas_delta = vent.filter(fecha_venta__range=[instance.fecha_inicio, instance.fecha_fin])
        instance.ventas.add(*ventas_delta)

serializers:

class VentasSerializer(serializers.ModelSerializer):
    class Meta:
        model = Ventas
        fields = [<your fields here>,]

class ReporteSerializer(serializers.ModelSerializer): 
    ventas = VentasSerializer(read_only=True, many=True)

    class Meta: 
        model = Reporte 
        fields = ('fecha_inicio', 'fecha_fin','ventas',) 
  • Tried this but it still wont save. I make a print(instance.ventas) to see from the command log when it saves and it returns Venta.none and when I see it from the django admin panel it also doesn't hightlight the selected ones – Ildebrando Quinchoa Aug 18 '22 at 17:37
  • To see those you'd have to do print(instance.ventas.all()) – Peter Gardiner Aug 18 '22 at 17:48
  • I was doint that bad, but it stwill wont save. Now it does print the ventas in the instance but when I look for it in a rest view it appears empty – Ildebrando Quinchoa Aug 18 '22 at 18:05
  • What does your rest view code look like? – Peter Gardiner Aug 18 '22 at 18:10
  • my serializer is class ReporteSerializer(serializers.ModelSerializer): class Meta: model = Reporte fields = ('fecha_inicio', 'fecha_fin','ventas',) To some reports I added manually some ventas and those shows in the endpoint but for the ones I'm creating now they dont show the values that are printed when i do (instance.ventas.all()) – Ildebrando Quinchoa Aug 18 '22 at 18:13
  • You will need a serializer for ventas. I'll edit my answer – Peter Gardiner Aug 18 '22 at 18:17
  • As you can see in the updated answer you needed to have your ventas field reflect the fact that it is a m2m relation by linking it as its own serializer – Peter Gardiner Aug 18 '22 at 18:23
  • Saving is not needed, but it also does not severely impact this. The method he's using is post_save, and he has a check to see if the instance was created. If it was created, only then he executes the code. The second iteration it wouldn't go through the `if` – nigel239 Aug 18 '22 at 18:27
  • 1
    Good point. I'll edit the answer – Peter Gardiner Aug 18 '22 at 18:32
  • Solved it. The problem was, as I understood, that in the post_save the m2m data is deleted and it needs to be accessed from the admin model using save_related basically doing the same I do in the post_save. Here are the links that helped me, and thanks for helping me https://stackoverflow.com/questions/35047356/django-post-save-signal-and-manytomanyfield-and-django-admin https://timonweb.com/django/many-to-many-field-save-method-and-the-django-admin-caveat/ https://stackoverflow.com/questions/1925383/issue-with-manytomany-relationships-not-updating-immediately-after-save/1925784#1925784 – Ildebrando Quinchoa Aug 18 '22 at 18:37
-1

after using instance.ventas.add() you have to use instance.save(), that is becouse you create the object but you don't save it yet.

@receiver(post_save, sender=Reporte)
def guarda_venta(sender, instance, created, **kwargs):
    if created:
        vent = Venta.objects.all()
        ventas_delta = vent.filter(fecha_venta__range=[instance.fecha_inicio, instance.fecha_fin])
        instance.ventas.add(*ventas_delta)
        instance.save()