Skip to main content

autoupdated database fields for model methods

Project description

build Coverage Status

django-computedfields

django-computedfields provides autoupdated database fields for model methods.

Tested with Django 3.2 and 4.2 (Python 3.8 to 3.11).

Example

Just derive your model from ComputedFieldsModel and place the @computed decorator at a method:

from django.db import models
from computedfields.models import ComputedFieldsModel, computed

class MyModel(ComputedFieldsModel):
    name = models.CharField(max_length=32)

    @computed(models.CharField(max_length=32), depends=[('self', ['name'])])
    def computed_field(self):
        return self.name.upper()

computed_field will be turned into a real database field and can be accessed and searched like any other database field. During saving the associated method gets called and it’s result written to the database.

How to recalculate without saving the model record

If you need to recalculate the computed field but without saving it, use from computedfields.models import compute

>>> from computedfields.models import compute
>>> person = MyModel.objects.get(id=1)  # this is to retrieve existing record
>>> person.computed_field               # outputs 'BERTY'
>>> person.name = 'nina'                # changing the dependent field `name` to nina
>>> compute(person, 'computed_field')   # outputs 'NINA'
>>> person.computed_field               # outputs 'BERTY' because the `person` is not yet saved
>>> person.save()                       # alters the database record for `name` and `computed_field`
>>> person.computed_field               # outputs 'NINA'

depends keyword

The depends keyword argument can be used with any relation to indicate dependencies to fields on other models as well:

from django.db import models
from computedfields.models import ComputedFieldsModel, computed

class MyModel(ComputedFieldsModel):
    name = models.CharField(max_length=32)
    fk = models.ForeignKey(SomeModel)

    @computed(
        models.CharField(max_length=32),
        depends=[
            ('self', ['name']),
            ('fk', ['fieldname'])
        ]
    )
    def computed_field(self):
        return self.name.upper() + self.fk.fieldname

Now changes to self.name, fk or fk.fieldname will update computed_field.

Alternative Syntax

Instead of using the @computed decorator with inline field definitions, you can also use a more declarative syntax with ComputedField, example from above rewritten:

from django.db import models
from computedfields.models import ComputedFieldsModel, ComputedField

def get_upper_string(inst):
    return inst.name.upper()

class MyModel(ComputedFieldsModel):
    name = models.CharField(max_length=32)
    computed_field = ComputedField(
        models.CharField(max_length=32),
        depends=[('self', ['name'])],
        compute=get_upper_string
    )

Documentation

The documentation can be found here.

Changelog

  • 0.2.10

    • Fix related_query_name on M2M relations
    • Fix computed fk fields to use instances and not the _id attribute
    • Fix UNIONed resolver updates, that contain prefetches
    • Fix thread isolation in signal handlers
  • 0.2.9

    • fix related_query_name issue
  • 0.2.8

    • Django 5.2 support
  • 0.2.7

    • setuptools issue fixed
  • 0.2.6

    • Django 5.1 support
  • 0.2.5

    • Django 5.0 & Python 3.12 support
    • Django 3.2 support dropped
  • 0.2.4

    • performance improvement: use OR for simple multi dependency query construction
    • performance improvement: better queryset narrowing for M2M lookups
    • ComputedField for a more declarative code style added
  • 0.2.3

    • performance improvement: use UNION for multi dependency query construction
  • 0.2.2

    • Django 4.2 support
    • Use model._base_manager instead of model.objects to prevent using overridden models.objects with a custom manager
  • 0.2.1

    • Django 4.1 support
  • 0.2.0 - next beta release

    • new features:

      • better memory control for the update resolver via COMPUTEDFIELDS_QUERYSIZE or as argument on @computed
      • update optimization - early update-tree exit
      • faster updates with COMPUTEDFIELDS_FASTUPDATE
      • checkdata command
      • showdependencies command
      • typing support for computed fields
    • enhancements:

      • better updatedata command
    • removed features:

      • transitive reduction on intermodel graph (due to negative impact)
      • pickled resolver map (due to showing low benefit)
      • update_dependent_multi and preupdate_dependent_multi (due to showing low benefit and being a code nuisance)
      • Django 2.2 shims removed
    • bug fixes:

      • regression on proxy models fixed
      • sliced querset support for mysql fixed
  • 0.1.7

    • add list type support for update_fields in signal handlers
  • 0.1.6

    • maintenace version with CI test dependencies changes:

      • removed Python 3.6
      • removed Django 2.2
      • added Python 3.10
      • added Django 4.0
      • move dev environment to Python 3.10 and Django 3.2

      Note that Django 2.2 will keep working until real incompatible code changes occur. This may happen by any later release, thus treat 0.1.6 as last compatible version.

  • 0.1.5

    • fix error on model instance cloning
  • 0.1.4

    • Django 3.2 support
  • 0.1.3

    • better multi table inheritance support and test cases
    • explicit docs for multi table inheritance
  • 0.1.2

    • bugfix: o2o reverse name access
    • add docs about model inheritance support
  • 0.1.1

    • bugfix: add missing migration
  • 0.1.0

    • fix recursion on empty queryset
    • dependency expansion on M2M fields
    • m2m_changed handler with filtering on m2m fields
    • remove custom metaclass, introducing Resolver class
    • new decorator @precomputed for custom save methods
    • old depends syntax removed
    • docs update
  • 0.0.23:

    • Bugfix: Fixing leaking computed fields in model inheritance.
  • 0.0.22:

    • Automatic dependency expansion on reverse relations.
    • Example documentation.
  • 0.0.21:

    • Bugfix: Fixing undefined _batchsize for pickled map usage.
  • 0.0.20

    • Use bulk_update for computed field updates.
    • Allow custom update optimizations with select_related and prefetch_related.
    • Respect computed field MRO in compute.
    • Allow updates on local computed fields from update_dependent simplifying bulk actions on ComputedFieldsModel.
  • 0.0.19

    • Better graph expansion on relation paths with support for update_fields.
  • 0.0.18

    • New depends syntax deprecating the old one.
    • MRO of local computed field methods implemented.
  • 0.0.17

    • Dropped Python 2.7 and Django 1.11 support.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_computedfields-0.2.10.tar.gz (476.8 kB view details)

Uploaded Source

Built Distribution

django_computedfields-0.2.10-py3-none-any.whl (453.8 kB view details)

Uploaded Python 3

File details

Details for the file django_computedfields-0.2.10.tar.gz.

File metadata

  • Download URL: django_computedfields-0.2.10.tar.gz
  • Upload date:
  • Size: 476.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.12

File hashes

Hashes for django_computedfields-0.2.10.tar.gz
Algorithm Hash digest
SHA256 ccffe468a0dd6e70463e72ac7dd0572df3f97f7bde828e379a83a8f9d555cf66
MD5 4b4583a930d30e7b14b646f543106a75
BLAKE2b-256 70db00989939198a72191118d70e838817d3be78e51a53033b58524ff7b7137e

See more details on using hashes here.

File details

Details for the file django_computedfields-0.2.10-py3-none-any.whl.

File metadata

File hashes

Hashes for django_computedfields-0.2.10-py3-none-any.whl
Algorithm Hash digest
SHA256 ff89f611b212fd7c8f7fcf6146d41a737c56c24e59f3d6f5aff0054b9f475597
MD5 8b366d7d8c262ecb836e0334f3739420
BLAKE2b-256 1eabc578c416a63e884c8eb1162ccbff8904c75fb92248f4f37cbae6fadec257

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page