django-relativedelta
====================
.. image:: https://travis-ci.org/CodeYellowBV/django-relativedelta.svg?branch=master
:target: https://travis-ci.org/CodeYellowBV/django-relativedelta
A Django field for the `dateutil.relativedelta.relativedelta <http://dateutil.readthedocs.io/en/stable/relativedelta.html>`_ class,
which conveniently maps to the `PostgreSQL INTERVAL type <https://www.postgresql.org/docs/current/static/datatype-datetime.html#DATATYPE-INTERVAL-INPUT>`_.
The standard `Django DurationField <https://docs.djangoproject.com/en/1.10/ref/models/fields/#durationfield>`_
maps to `Python's datetime.timedelta <https://docs.python.org/3/library/datetime.html#datetime.timedelta>`_, which
has support for days and weeks, but not for years and months. And if you try to read an ``INTERVAL`` that contains
months anyway, information is lost because each month gets converted to 30 days.
For compatibility, a `VARCHAR` field is used on other databases. This
uses a custom relativedelta representation. However, this means that
true in-database interval operations are not supported in these
databases. Sorting and comparing between two relativedelta fields or
a relativedelta field and a fixed relativedelta value is supported,
however.
You should use this package when you need to store payment intervals
(which tend to be monthly or quarterly), publication intervals (which
can be weekly but also monthly) and so on, or when you simply don't
know what the intervals are going to be and want to offer some
flexibility.
If you want to use more advanced recurring dates, you should consider
using `django-recurrence <https://github.com/django-recurrence/django-recurrence>`_
instead. This maps to the `dateutil.rrule.rrule <http://dateutil.readthedocs.io/en/stable/rrule.html>`_
class, but it doesn't use native database field types, so you can't
perform arithmetic on them within the database.
Usage
-----
Using the field is straightforward. You can add the field to your
model like so:
.. code:: python
from django.db import models
from relativedeltafield import RelativeDeltaField
class MyModel(models.Model):
rdfield=RelativeDeltaField()
Then later, you can use it:
.. code:: python
from dateutil.relativedelta import relativedelta
rd = relativedelta(months=2,days=1,hours=6)
my_model = MyModel(rdfield=rd)
my_model.save()
Or, alternatively, you can use a string with the
`ISO8601 "format with designators" time interval syntax <https://www.postgresql.org/docs/current/static/datatype-datetime.html#DATATYPE-INTERVAL-INPUT>`_:
.. code:: python
from dateutil.relativedelta import relativedelta
my_model = MyModel(rdfield='P2M1DT6H')
my_model.save()
For convenience, a standard Python ``datetime.timedelta`` object is
also accepted:
.. code:: python
from datetime import timedelta
td = timedelta(days=62,hours=6)
my_model = MyModel(rdfield=td)
my_model.save()
After a ``full_clean()``, the object will always be converted to a
_normalized_ ``relativedelta`` instance. It is highly recommended
you use the `django-fullclean <https://github.com/fish-ball/django-fullclean>`_
app to always force ``full_clean()`` on ``save()``, so you can be
sure that after a ``save()``, your fields are both normalized
and validated.
Limitations and pitfalls
------------------------
Because this field is backed by an ``INTERVAL`` column, it neither
supports the relative ``weekday``, ``leapdays``, ``yearday`` and
``nlyearday`` arguments, nor the absolute arguments ``year``,
``month``, ``day``, ``hour``, ``second`` and ``microsecond``.
The ``microseconds`` field is converted to a fractional ``seconds``
value, which might lead to some precision loss due to floating-point
representation.
The ``weeks`` field is "virtual", being derived from the multiple of 7
days. Thus, any week value in the input interval specification is
converted to days and added to the ``days`` field of the interval.
When serializing back to a string, weeks will never be written.
Similarly, if the interval contains a multiple of 7 days, you can read
this back out from the ``weeks`` property.
Support for databases other than PostgreSQL is limited.
For consistency reasons, when a relativedelta object is assigned to a
RelativeDeltaField, it automatically calls ``normalized()`` on
``full_clean``. This ensures that the database representation is as
similar to the relativedelta as possible (for instance, fractional
days are always converted to hours).
Raw data
{
"_id": null,
"home_page": "https://github.com/CodeYellowBV/django-relativedelta",
"name": "django-relativedelta",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "django,",
"author": "Code Yellow B.V.",
"author_email": "django-relativedelta@codeyellow.nl",
"download_url": "https://files.pythonhosted.org/packages/fc/82/cc3910164559a063e9bf3cdb4214ed57dbaa1395cd9ad37b4b958997accb/django-relativedelta-2.0.0.tar.gz",
"platform": null,
"description": "django-relativedelta\n====================\n\n.. image:: https://travis-ci.org/CodeYellowBV/django-relativedelta.svg?branch=master\n :target: https://travis-ci.org/CodeYellowBV/django-relativedelta\n\nA Django field for the `dateutil.relativedelta.relativedelta <http://dateutil.readthedocs.io/en/stable/relativedelta.html>`_ class,\nwhich conveniently maps to the `PostgreSQL INTERVAL type <https://www.postgresql.org/docs/current/static/datatype-datetime.html#DATATYPE-INTERVAL-INPUT>`_.\n\nThe standard `Django DurationField <https://docs.djangoproject.com/en/1.10/ref/models/fields/#durationfield>`_\nmaps to `Python's datetime.timedelta <https://docs.python.org/3/library/datetime.html#datetime.timedelta>`_, which\nhas support for days and weeks, but not for years and months. And if you try to read an ``INTERVAL`` that contains\nmonths anyway, information is lost because each month gets converted to 30 days.\n\nFor compatibility, a `VARCHAR` field is used on other databases. This\nuses a custom relativedelta representation. However, this means that\ntrue in-database interval operations are not supported in these\ndatabases. Sorting and comparing between two relativedelta fields or\na relativedelta field and a fixed relativedelta value is supported,\nhowever.\n\nYou should use this package when you need to store payment intervals\n(which tend to be monthly or quarterly), publication intervals (which\ncan be weekly but also monthly) and so on, or when you simply don't\nknow what the intervals are going to be and want to offer some\nflexibility.\n\nIf you want to use more advanced recurring dates, you should consider\nusing `django-recurrence <https://github.com/django-recurrence/django-recurrence>`_\ninstead. This maps to the `dateutil.rrule.rrule <http://dateutil.readthedocs.io/en/stable/rrule.html>`_\nclass, but it doesn't use native database field types, so you can't\nperform arithmetic on them within the database.\n\nUsage\n-----\n\nUsing the field is straightforward. You can add the field to your\nmodel like so:\n\n.. code:: python\n\n from django.db import models\n from relativedeltafield import RelativeDeltaField\n\n class MyModel(models.Model):\n rdfield=RelativeDeltaField()\n\nThen later, you can use it:\n\n.. code:: python\n\n from dateutil.relativedelta import relativedelta\n\n rd = relativedelta(months=2,days=1,hours=6)\n my_model = MyModel(rdfield=rd)\n my_model.save()\n\n\nOr, alternatively, you can use a string with the\n`ISO8601 \"format with designators\" time interval syntax <https://www.postgresql.org/docs/current/static/datatype-datetime.html#DATATYPE-INTERVAL-INPUT>`_:\n\n.. code:: python\n\n from dateutil.relativedelta import relativedelta\n\n my_model = MyModel(rdfield='P2M1DT6H')\n my_model.save()\n\n\nFor convenience, a standard Python ``datetime.timedelta`` object is\nalso accepted:\n\n.. code:: python\n\n from datetime import timedelta\n\n td = timedelta(days=62,hours=6)\n my_model = MyModel(rdfield=td)\n my_model.save()\n\nAfter a ``full_clean()``, the object will always be converted to a\n_normalized_ ``relativedelta`` instance. It is highly recommended\nyou use the `django-fullclean <https://github.com/fish-ball/django-fullclean>`_\napp to always force ``full_clean()`` on ``save()``, so you can be\nsure that after a ``save()``, your fields are both normalized\nand validated.\n\n\nLimitations and pitfalls\n------------------------\n\nBecause this field is backed by an ``INTERVAL`` column, it neither\nsupports the relative ``weekday``, ``leapdays``, ``yearday`` and\n``nlyearday`` arguments, nor the absolute arguments ``year``,\n``month``, ``day``, ``hour``, ``second`` and ``microsecond``.\n\nThe ``microseconds`` field is converted to a fractional ``seconds``\nvalue, which might lead to some precision loss due to floating-point\nrepresentation.\n\nThe ``weeks`` field is \"virtual\", being derived from the multiple of 7\ndays. Thus, any week value in the input interval specification is\nconverted to days and added to the ``days`` field of the interval.\nWhen serializing back to a string, weeks will never be written.\nSimilarly, if the interval contains a multiple of 7 days, you can read\nthis back out from the ``weeks`` property.\n\nSupport for databases other than PostgreSQL is limited.\n\nFor consistency reasons, when a relativedelta object is assigned to a\nRelativeDeltaField, it automatically calls ``normalized()`` on\n``full_clean``. This ensures that the database representation is as\nsimilar to the relativedelta as possible (for instance, fractional\ndays are always converted to hours).\n",
"bugtrack_url": null,
"license": "MIT License",
"summary": "Django alternative to DurationField using dateutil.relativedelta",
"version": "2.0.0",
"split_keywords": [
"django",
""
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "913a0636c196b3e1965b8497064e45f55719ddf14f04b6e11ad4d5057da40346",
"md5": "d480d2542b0a496a5d80cb05b46a3aa5",
"sha256": "72b37b27eadc03b0b4869712363c37126445161f6880106468006e4b52a76e59"
},
"downloads": -1,
"filename": "django_relativedelta-2.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "d480d2542b0a496a5d80cb05b46a3aa5",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 8087,
"upload_time": "2023-04-04T14:31:08",
"upload_time_iso_8601": "2023-04-04T14:31:08.696030Z",
"url": "https://files.pythonhosted.org/packages/91/3a/0636c196b3e1965b8497064e45f55719ddf14f04b6e11ad4d5057da40346/django_relativedelta-2.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "fc82cc3910164559a063e9bf3cdb4214ed57dbaa1395cd9ad37b4b958997accb",
"md5": "9a331090e6a4c7d962d059e47d9ce480",
"sha256": "8a56bd5461dea35b74011f95be1d90d20caafe1f0c9be2fce8e8eefdf92e2cbe"
},
"downloads": -1,
"filename": "django-relativedelta-2.0.0.tar.gz",
"has_sig": false,
"md5_digest": "9a331090e6a4c7d962d059e47d9ce480",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 14200,
"upload_time": "2023-04-04T14:31:11",
"upload_time_iso_8601": "2023-04-04T14:31:11.161657Z",
"url": "https://files.pythonhosted.org/packages/fc/82/cc3910164559a063e9bf3cdb4214ed57dbaa1395cd9ad37b4b958997accb/django-relativedelta-2.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-04-04 14:31:11",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "CodeYellowBV",
"github_project": "django-relativedelta",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "django-relativedelta"
}