# This package is for logging every changes in your models in this format:
```json
{
field_name: {
    "old":  old_value, "new":  new_value | None if this is delete action
  }
}
```

Example
```json

{
  "price": {
    "old": "2425", "new": "645"
  }, 
  "name": {
    "old":  "ProductName", "new": "NewProductNmae"
  }
}
```

# USING
Add 'models_logging' at the end of INSTALLED_APPS in settings.py!
This is important because models connect to save and init signals when apps is ready

1.
```python
INSTALLED_APPS = (
    ...,
    'models_logging',
)
```

If request.user is not represented by AUTH_USER_MODEL in your application then you can set up a custom Users model:

```python
LOGGING_USER_MODEL = 'yourapp.Users'
# By default, LOGGING_USER_MODEL = AUTH_USER_MODEL
```



2. make migrations
3. add the models you want to log in settings.py, format:
```python
LOGGING_MODELS = (
    'app.ClassName',    # logging only for this model
    'another_app'     # logging of all models in this app
)
```

Sometimes object.save() operation can be called many times per 1 request.
Per each .save() models_logging creates Change, so your database can quickly grow to a very large size
for prevent this "bug" you can add middleware in settings.py
```python
MIDDLEWARE = (
    ...,
    'models_logging.middleware.LoggingStackMiddleware',     # it merge all changes of object per request
)
```

or use context_manager from models_logging.utils in your view or script
```python
from models_logging.utils import create_merged_changes

def your_script():
    with create_merged_changes():
        ...
```


You can add model for ignore logging
settings.py
```python
LOGGING_EXCLUDE = (
    'app'     # ignore logging of all models in this app
    'another_app.Model'     # ignore logging for this model
)
```


Also you can set up permission for the logging records
Make func (it will be called in admin) or bool
settings.py
```python
def can_revert(request, obj):
    return request.user.username == 'myusername'

LOGGING_REVERT_IS_ALLOWED = can_revert
LOGGING_CAN_DELETE_REVISION = can_revert
LOGGING_CAN_DELETE_CHANGES = False
LOGGING_CAN_CHANGE_CHANGES = True
```

in models you can set attributes:
```python
LOGGING_IGNORE_FIELDS = ()  # to ignore changes of some fields

# OR

LOGGING_ONLY_FIELDS  = ()    # to save changes of only those fields 
```
 
 
If you want to watch changes in admin/history of your object you can use models_logging.admin.HistoryAdmin
```python
from models_logging.admin import HistoryAdmin


class YourAdminModel(HistoryAdmin):
    history_latest_first = False    # latest changes first
    inline_models_history = '__all__'   # __all__ or list of inline models for this ModelAdmin

```

You can implement your own JSONEncoder and set path to it in django settings
```python
LOGGING_JSON_ENCODER = 'path.to.your.JsonEncoder'
```


Version > 1.0 is incompatible with old versions (requires django >= 2.0)
for django <= 2.0 use 0.9.7 version
 


PS: It's not a backup your database, don't try to revert "huge" Revisions
Recovering changes it's at least 1 hit to database (save or delete),
if you run recovering thousands of changes this will be very slowly
