Watching Changes to ForeignKey Fields¶
ForeignKey Reference Changes¶
You can watch whether a foreign key reference changes by putting the name of the FK field in the when
parameter:
class Organization(models.Model):
name = models.CharField(max_length=100)
class UserAccount(LifecycleModel):
username = models.CharField(max_length=100)
email = models.CharField(max_length=600)
employer = models.ForeignKey(Organization, on_delete=models.SET_NULL)
@hook(AFTER_UPDATE, condition=WhenFieldHasChanged("employer", has_changed=True))
def notify_user_of_employer_change(self):
mail.send_mail("Update", "You now work for someone else!", [self.email])
To be clear: This hook will fire when the value in the database column that stores the foreign key (in this case, organization_id
) changes. Read on to see how to watch for changes to fields on the related model.
ForeignKey Field Value Changes¶
You can have a hooked method fire based on the value of a field on a foreign key-related model using dot-notation:
class Organization(models.Model):
name = models.CharField(max_length=100)
class UserAccount(LifecycleModel):
username = models.CharField(max_length=100)
email = models.CharField(max_length=600)
employer = models.ForeignKey(Organization, on_delete=models.SET_NULL)
@hook(AFTER_UPDATE, condition=WhenFieldValueChangesTo("employer.name", value="Google"))
def notify_user_of_google_buy_out(self):
mail.send_mail("Update", "Google bought your employer!", ["to@example.com"],)
.select_related()
, i.e. UserAccount.objects.select_related("organization")
for the example above. If you don't do this, you will almost certainly experience a major N+1 performance problem.