Glad it helped, Marco,
Just to be doubly sure, the update_or_create()
method only updates the fields with the values in the default dictionary. It will not use the kwargs
for updating. As an exampe:
# use visit, patient and professional to fetch an invoice
# This will only every fetch or create something.
# It won't, according to my experience and the docs, update anything.
invoice, created = Invoice.objects.update_or_create(
visit=visit,
pacient=visit.pacient,
professional=visit.professional
)
On the other hand, this will update patient
and professional
.
# use visit to fetch an invoice
# If Invoice with visit exists, update all fields in the defaults {}
# If invoice with visit doesn't exist, create an Invoice with the fields, values in defaults {}
invoice, created = Invoice.objects.update_or_create(
visit=visit,
defaults={
"patient": visit.patient,
"professional": visit.professional,
etc etc
}
)
Note also that you can query for an object based on a kwarg, in your case visit
, and also update it by including it in the defaults dict.
Take a look at the update_or_create()
docs in the link I sent. The relevant paragraph is:
The update_or_create
method tries to fetch an object from database based on the given kwargs
. If a match is found, it updates the fields passed in the defaults
dictionary.
Actually, now that I’m just reading your post again, I think I’ve misunderstood you. You’re saying that you don’t need to update the Invoice
because you can update all its information by changing the value of the fields in a Visit
instance? Have I understood you correctly? And apologies if I have.
As for the save()
method from a FormSet
and Form
, I’m going to have to plead ignorance, as I spend all my time in Django Rest Framework and have very limited experience with forms so everything I write here should be taken with a grain of salt. And perhaps there is someone wiser who can give you some advice here.
Let’s say you are creating a Visit
as you have defined above, you can override it’s save method to create or update an Invoice. I should say that this is just an idea, I’m sure there are others who might know of a more elegant way of doing it directly from interaction with the Formset
class Visit(models.Model):
id = primary_key
patient =
professional =
def save(self, *args, **kwargs):
self.do_something_to_invoice()
return super().save(*args, **kwargs)
def do_something_to_invoice(self):
invoice, _ = Invoice.objects.update_or_create(
visit=self.id,
defaults={
"patient":self.patient,
"professional"=self.professional
}
)
Did I answer your question or. am I way off?
Cheers,
Conor