django-oscar / django-oscar-accounts

Managed accounts for Django (with or without django-oscar)
BSD 3-Clause "New" or "Revised" License
212 stars 119 forks source link

Account.save() fails in Django 4.2 #179

Open robertgalloway-nobleai opened 4 months ago

robertgalloway-nobleai commented 4 months ago

In Django 4.2, calling manager methods on non-persisted instances is no longer allowed. This change causes Account.save() to fail on any Account that hasn't been previously saved, because the Account._balance() method calls self.transactions.aggregate() before the Account is in the database:

  File ".../helpers.py", line 320, in create_account
    account_type.accounts.create(
  File ".../lib/python3.8/site-packages/django/db/models/fields/related_descriptors.py", line 799, in create
    return super(RelatedManager, self.db_manager(db)).create(**kwargs)
  File ".../lib/python3.8/site-packages/django/db/models/manager.py", line 87, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File ".../lib/python3.8/site-packages/django/db/models/query.py", line 658, in create
    obj.save(force_insert=True, using=self.db)
  File ".../lib/python3.8/site-packages/oscar_accounts/abstract_models.py", line 149, in save
    self.balance = self._balance()
  File ".../lib/python3.8/site-packages/oscar_accounts/abstract_models.py", line 153, in _balance
    aggregates = self.transactions.aggregate(sum=Sum('amount'))
  File ".../lib/python3.8/site-packages/django/db/models/manager.py", line 87, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File ".../lib/python3.8/site-packages/django/db/models/fields/related_descriptors.py", line 718, in get_queryset
    raise ValueError(
ValueError: 'Account' instance needs to have a primary key value before this relationship can be used.