Metadata-Version: 2.4
Name: django-strategy-field
Version: 3.2
Summary: custom fields useful to implement the Strategy Pattern with Django models.
Project-URL: downloads, https://github.com/saxix/django-strategy-field
Project-URL: homepage, https://github.com/saxix/django-strategy-field
Author-email: sax <s.apostolico@gmail.com>
License: MIT License
        
        Copyright (c) 2010-2020, Stefano Apostolico (s.apostolico@gmail.com)
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        Any use in a commercial product must be notified to the author by email
        indicating company name and product name
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Framework :: Django :: 3.2
Classifier: Framework :: Django :: 4.2
Classifier: Framework :: Django :: 5.2
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/markdown

# django-strategy-field

[![Pypi](https://badge.fury.io/py/django-strategy-field.svg)](https://badge.fury.io/py/django-strategy-field)
[![coverage](https://codecov.io/github/saxix/django-strategy-field/coverage.svg?branch=develop)](https://codecov.io/github/saxix/django-strategy-field?branch=develop)
[![Test](https://github.com/saxix/django-strategy-field/actions/workflows/test.yml/badge.svg)](https://github.com/saxix/django-strategy-field/actions/workflows/test.yml)
[![Django](https://img.shields.io/pypi/frameworkversions/django/django-strategy-field)](https://pypi.org/project/django-strategy-field/)


Set of custom fields useful to implement the [Strategy Pattern](http://www.oodesign.com/strategy-pattern.html) with Django models.

The Strategies are displayed in SelectBoxes as standard choice field

This package provides the following custom fields:

* StrategyField
* MultipleStrategyField
* StrategyClassField
* MultipleStrategyClassField

The StrategyField can be accessed as instance of the model with an attribute
``context`` that points to model that 'owns' the field (inverse relation). So:

## Example


```python

    from strategy_field.fields import StrategyField
    from django.core.mail.backends.filebased.EmailBackend


    class Event(models.Model):
        backend = StrategyField()

    Event(sender='django.core.mail.backends.filebased.EmailBackend')

```

## Use case


As example we can imagine an application that manages `Events` that need to be notified to users.
Each `Occurrence` of `Event` can be notified using different transport, (email, sms,...).
We want to be able to add/change the way we send notification, per event basis, simply using
the Django admin panel.

```python

    from strategy_field.fields import StrategyField
    from strategy_field.registry import Registry

    class TransportRegistry(Registry)
        pass

    class AbstractStrategy(object):
        def __init__(self, context):
            self.context = context

        def send(self):
            raise NotImplementedError

    class EmailStrategy(AbstractTransport):
        def send(self):
            ...

    class SMSStrategy(AbstractTransport):
        def send(self):
            ...
    registry = TransportRegistry(AbstractStrategy)
    registry.register(EmailStrategy)
    registry.register(SMSStrategy)

    class Event(models.Model):
        sender = StrategyField(registry=registry)

    Event.objects.get_or_create(sender=EmailStrategy)
    ...
    ...
    e = Event.objects.get(sender=EmailStrategy)
    e.sender.send() # e.sender.context == e

```

### More examples


*Use callable*


```python

    from strategy_field.fields import StrategyField
    from strategy_field.registry import Registry

    registry1 = Registry()
    registry2 = Registry()

    class A(model):
        sender = StrategyField(registry=lambda model: model._registry)
        class Meta:
            abstract = True

    class C1(A):
        _registry = registry1
        class Meta:
            abstract = True

    class C2(A):
        _registry = registry2
        class Meta:
            abstract = True

```
