Saving a model on another model save()

Django has a super neat model object method called update_or_create().

https://docs.djangoproject.com/en/3.1/ref/models/querysets/

In your case, say you wanted to create or update an invoice, you could execute the following:

Invoice.objects.update_or_create(
    id=<id>,
    defaults={"date":visit.date}
)

This will look for a record with an id=<id> and then update the items in the default dict if the record exists, else it will create one.

The caveat with this method is you have to have something unique, and which you create yourself which that you can use as the lookup field. So ideally you would manage Invoice.id yourself.

If you can’t use the ID as the lookup as they’re created automatically, you can define your own unique constraints in your model, which you can then use when looking up an object.

For example:

class Invoicel(models.Model):
   id = auto int
   date = date
   dogs_name = 
   cats_name =

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=["dogs_name", "cats_name"], name="unique_invoice"
            )
        ]

You could then do a lookup like this:

Invoice.objects.update_or_create(
    cats_name=name,
    dogs_name=name,
    defaults={
        "date":visit.date,
        "dogs_name": new_name,
        "cats_name": another_new_name
    }
)

Saying all that, if the above code is only written once in your app, then I see little wrong with it. It effectively does what the update_or_create() method does, although there is more error handling in the update_or_create() method.

Another thing which you can look at is overriding the save() method of Visit and do some logic there. As an example:

class Visit(models.Mode):
     attribute = 
     etc etc etc

    def save(self, *args, **kwargs):
        # do something with Invoice here
        return super().save(*args, **kwargs)

And if you really must, you can look at using Django’s signals.

Hope some of this may be of help.

3 Likes