How can I link an object on save in django to an existing one if there is a matching value between them?

I’m using Django and DRF to to reconcile two lists of data (promises to pay, and payments). When uploading new payments, if the payment transaction ID shares the same ID as a promise to pay, I want to link them by saving the corresponding promise in the payment’s foreign key field.

I have two models:

class Promise(models.Model):
     transaction_id = models.CharField(max_length=50)
     amount_promised = models.DecimalField(decimal_places=2, max_digits=8)
     created_on = models.DateTimeField(auto_now_add=True)

class Payment(models.Model):
    promise = models.OneToOneField(Promise, on_delete=models.CASCADE, blank=True)
    transaction_id = models.CharField(max_length=50)
    amount_paid = models.DecimalField(decimal_places=2, max_digits=8)
    created_on = models.DateTimeField(auto_now_add=True)

and two views:

class PromiseViewSet(viewsets.ModelViewSet):
    permission_classes = (IsCreatorOrReadOnly,)
    queryset = Promise.objects.all()
    serializer_class = PromiseSerializer

class PaymentViewSet(viewsets.ModelViewSet):
    permission_classes = (IsCreatorOrReadOnly,)
    queryset = Payment.objects.all()
    serializer_class = PaymentSerializer

My understanding is this requires a custom save method, but I’m not certain if the magic should be happening in views or models. Either way, the logic should be something like:

  • Loop through promises…if the new payment.transaction_id = a promise.transaction_id, break and link the two together by saving the promise.pk to the promise foreign key in the newly created payment object.

And the solution would look something like this:

warning, this is rough!

def save(self, *args, **kwargs):
    
    #check if promise ID was manually entered, if not continue
    if self.promise is None:
        for transaction_id in Promise.transaction_id:

            if transaction_id = self.transaction_id:
                return Promise.pk
                self.promise = Promise.pk  

    else:
        .save()

    super(Payment, self).save(*args, **kwargs)

Go to Source
Author: Mike