Skip to content

Commit

Permalink
Move quickstart docs to their own page so that they appear in the PDF…
Browse files Browse the repository at this point in the history
… docs.

Also improve code examples in all the docs.
  • Loading branch information
LincolnPuzey committed Mar 20, 2022
1 parent 9eb6002 commit cb71739
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 89 deletions.
32 changes: 15 additions & 17 deletions docs/advanced.rst
Expand Up @@ -4,18 +4,17 @@ Advanced Usage

Verbose mode
------------
By default, when you use ``get_dirty_fields()`` function, if there are dirty fields, only the old value is returned.
You can use ``verbose`` option to return the saved and current value:
By default, when you use ``get_dirty_fields()`` function, if there are dirty fields, only the saved value is returned.
You can use the ``verbose`` option to return the saved and current in-memory value:

.. code-block:: python
.. code-block:: pycon
>>> model = ExampleModel.objects.create(characters="first value")
>>> model.characters = "second value"
>>> model.get_dirty_fields()
{'boolean': True, 'characters': 'first_value'}
{'characters': 'first_value'}
>>> model.get_dirty_fields(verbose=True)
{
'boolean': {'saved': True, 'current': False},
'characters': {'saved': "first value", 'current': 'second value'}
}
{'characters': {'saved': 'first value', 'current': 'second value'}}
Checking foreign key fields.
Expand All @@ -28,17 +27,16 @@ use ``check_relationship`` parameter:
class ForeignKeyModel(DirtyFieldsMixin, models.Model):
fkey = models.ForeignKey(AnotherModel, on_delete=models.CASCADE)
.. code-block:: pycon
>>> model = ForeignKeyModel.objects.create(fkey=obj1)
>>> model.is_dirty()
False
>>> model.fkey = obj2
>>> model.is_dirty()
False
>>> model.is_dirty(check_relationship=True)
True
>>> model.get_dirty_fields()
{}
>>> model.get_dirty_fields(check_relationship=True)
Expand All @@ -52,13 +50,13 @@ you can use ``save_dirty_fields()`` method.

Warning: This calls the ``save()`` method internally so will trigger the same signals as normally calling the ``save()`` method.

.. code-block:: python
.. code-block:: pycon
>>> model.get_dirty_fields()
{'boolean': True, 'characters': 'first_value'}
>>> model.is_dirty()
True
>>> model.save_dirty_fields()
>>> model.get_dirty_fields()
{}
>>> model.is_dirty()
False
Performance Impact
Expand Down Expand Up @@ -113,7 +111,7 @@ Here is a code example to illustrate the problem:
.. code-block:: python
# first create a model
model = ExampleModel.objects.create(boolean=True, characters="first")
model = ExampleModel.objects.create(characters="first")
# then make an edit in-memory, model becomes dirty
model.characters = "second"
assert model.is_dirty()
Expand Down
16 changes: 10 additions & 6 deletions docs/customisation.rst
Expand Up @@ -21,16 +21,18 @@ If you want to check these relations, you should set ``ENABLE_M2M_CHECK`` to ``T
ENABLE_M2M_CHECK = True
m2m_field = models.ManyToManyField(AnotherModel)
.. code-block:: pycon
>>> model = Many2ManyModel.objects.create()
>>> related_model = AnotherModel.objects.create()
>>> model.is_dirty()
False
>>> model.m2m_field.add(related_model)
>>> model.is_dirty()
False
>>> model.get_dirty_fields(check_m2m={'m2m_field': {related_model.id}})
>>> model.get_dirty_fields(check_m2m={"m2m_field": {related_model.id}})
{}
>>> model.get_dirty_fields(check_m2m={'m2m_field': set()})
>>> model.get_dirty_fields(check_m2m={"m2m_field": set()})
{'m2m_field': set([related_model.id])}
Expand All @@ -47,7 +49,9 @@ If you want to check a limited set of model fields, you should set ``FIELDS_TO_C
class ModelWithSpecifiedFields(DirtyFieldsMixin, models.Model):
boolean1 = models.BooleanField(default=True)
boolean2 = models.BooleanField(default=True)
FIELDS_TO_CHECK = ['boolean1']
FIELDS_TO_CHECK = ["boolean1"]
.. code-block:: pycon
>>> model = ModelWithSpecifiedFields.objects.create()
Expand Down Expand Up @@ -77,7 +81,7 @@ You can now define how you want to compare 2 values by passing a function on Dir
return new_value == old_value
class YourModel(DirtyFieldsMixin, models.Model):
compare_function = (your_function, {'param1': 5})
compare_function = (your_function, {"param1": 5})
Have a look at ``dirtyfields.compare`` module to get some examples.
Expand Down Expand Up @@ -111,8 +115,8 @@ being passed as well:
return value
def get_user_timezone():
return 'Europe/London'
return "Europe/London"
class YourModel(DirtyFieldsMixin, models.Model):
normalise_function = (your_normalise_function,
{'timezone': get_user_timezone()})
{"timezone": get_user_timezone()})
3 changes: 3 additions & 0 deletions docs/description.rst
@@ -0,0 +1,3 @@

``django-dirtyfields`` is a small library for tracking dirty fields on a Django model instance.
Dirty means that a field's in-memory value is different to the saved value in the database.
69 changes: 3 additions & 66 deletions docs/index.rst
Expand Up @@ -2,80 +2,17 @@
Welcome to django-dirtyfields's documentation!
==============================================

``django-dirtyfields`` is a small library for tracking dirty fields on a Django model instance.
Dirty means that a field's in-memory value is different to the value in the database.
.. include:: description.rst


Table of Contents:
------------------

.. toctree::
:maxdepth: 2
:maxdepth: 3

Quickstart <self>
quickstart
advanced
customisation
contributing
credits


Quickstart
==========


Install
-------

.. code-block:: bash
$ pip install django-dirtyfields
Usage
-----

To use ``django-dirtyfields``, you need to:

- Inherit from ``DirtyFieldsMixin`` in the Django model you want to track.

.. code-block:: python
from django.db import models
from dirtyfields import DirtyFieldsMixin
class ExampleModel(DirtyFieldsMixin, models.Model):
"""A simple example model to test dirty fields mixin with"""
boolean = models.BooleanField(default=True)
characters = models.CharField(blank=True, max_length=80)
- Use one of these 2 functions on a model instance to know if this instance is dirty, and get the dirty fields:

* ``is_dirty()``
* ``get_dirty_fields()``


Example
-------

.. code-block:: python
>>> model = ExampleModel.objects.create(boolean=True,
characters="first value")
>>> model.is_dirty()
False
>>> model.get_dirty_fields()
{}
>>> model.boolean = False
>>> model.characters = "second value"
>>> model.is_dirty()
True
>>> model.get_dirty_fields()
{'boolean': True, "characters": "first_value"}
Why would you want this?
------------------------

When using :mod:`django:django.db.models.signals` (:data:`django.db.models.signals.pre_save` especially), it is useful to be able to see what fields have changed or not. A signal could change its behaviour depending on whether a specific field has changed, whereas otherwise, you only could work on the event that the model's :meth:`~django.db.models.Model.save` method had been called.
61 changes: 61 additions & 0 deletions docs/quickstart.rst
@@ -0,0 +1,61 @@
Quickstart
==========


.. include:: description.rst


Installation
------------

.. code-block:: bash
$ pip install django-dirtyfields
Usage
-----

To use ``django-dirtyfields``, you need to:

- Inherit from the ``DirtyFieldsMixin`` class in the Django model you want to track dirty fields.

.. code-block:: python
from django.db import models
from dirtyfields import DirtyFieldsMixin
class ExampleModel(DirtyFieldsMixin, models.Model):
"""A simple example model to test dirtyfields with"""
characters = models.CharField(max_length=80)
- Use one of these 2 functions on a model instance to know if this instance is dirty, and get the dirty fields:

* ``is_dirty()``
* ``get_dirty_fields()``


Example
-------

.. code-block:: pycon
>>> model = ExampleModel.objects.create(characters="first value")
>>> model.is_dirty()
False
>>> model.get_dirty_fields()
{}
>>> model.characters = "second value"
>>> model.is_dirty()
True
>>> model.get_dirty_fields()
{'characters': 'first_value'}
Why would you want this?
------------------------

When using :mod:`django:django.db.models.signals` (:data:`django.db.models.signals.pre_save` especially),
it is useful to be able to see what fields have changed or not. A signal could change its behaviour
depending on whether a specific field has changed, whereas otherwise, you only could work on the event
that the model's :meth:`~django.db.models.Model.save` method had been called.

0 comments on commit cb71739

Please sign in to comment.