Opened 7 years ago
Closed 7 years ago
#28732 closed Bug (duplicate)
Deleted OneToOneRelation still referenced (not None) after refresh_from_db
Reported by: | JeroenPeterBos | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.9 |
Severity: | Normal | Keywords: | Refresh Database Object Delete |
Cc: | jeroenbosleusden2@… | Triage Stage: | Unreviewed |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Issue:
I ran into the following problem. I have a test that will retrieve an account which has a relation to ActivationCode. In the test i call a function that recieves a string with which it can find the activationcode, after that the funciton will call delete on the ActivationCode. Now the problem is, when i call refresh_from_db() on the account it will say that account still has a related Activation Code ( while it obviously hasn't ) and the problem is proved when i call on this related ActivationCode, because a DoesNotExist exception will be thrown.
In my oppinion also this deleted relation object should be reflected in account when refreshing it.
Below is the relevant code
Models
class Account(models.Model): user = models.OneToOneField(User) activated = models.BooleanField(default=False) class ActivationCode(models.Model): account = models.OneToOneField(Account, unique=True) code = models.CharField(max_length=128) timestamp = models.DateTimeField(auto_now_add=True)
Controller
def confirm(confirmData: dict) -> bool: """ Activates the account associated with the given code. :param confirmData: The data needed to confirm the account. :return: Whether the activation was successful. """ form = forms.ConfirmForm(confirmData) if not form.is_valid(): return False data = form.cleaned_data try: confirmObject = ActivationCode.objects.get(code=data['code']) except ActivationCode.DoesNotExist: return False confirmObject.account.activated = True confirmObject.account.save() confirmObject.delete() return True
The test that failes
class ActivateTest(TestCase): def setUp(self): controller.register(testUser) def testActivateSingleUser(self): account = User.objects.get(username=testUser['username']).account success = controller.confirm({'code': account.activationcode.code}) account.refresh_from_db() self.assertTrue(success) self.assertTrue(account.activated) # account.activationcode.refresh_from_db() # uncommenting this line will result in a DoesNotExist exception self.assertFalse(hasattr(account, 'activationcode')) # This test fails.
Finally the Traceback
FAIL: testActivateSingleUser (Main.tests.ActivateTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\Users\Path\To\Project\Main\tests.py", line 53, in testActivateSingleUser self.assertFalse(hasattr(account, 'activationcode')) AssertionError: True is not false
Duplicate of #27846, should be fixed in Django 2.0.