Package: cval-django-relativedelta
A Django field for thedateutil.relativedelta.relativedeltaclass,
which conveniently maps to thePostgreSQL INTERVAL type.The standardDjango DurationFieldmaps toPython’s datetime.timedelta, which
has support for days and weeks, but not for years and months.  And if you try to read anINTERVALthat contains
months anyway, information is lost because each month gets converted to 30 days.For compatibility, aVARCHARfield 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
usingdjango-recurrenceinstead.  This maps to thedateutil.rrule.rruleclass, but it doesn’t use native database field types, so you can’t
perform arithmetic on them within the database.UsageUsing the field is straightforward.  You can add the field to your
model like so:fromdjango.dbimportmodelsfromrelativedeltafieldimportRelativeDeltaFieldclassMyModel(models.Model):rdfield=RelativeDeltaField()Then later, you can use it:fromdateutil.relativedeltaimportrelativedeltard=relativedelta(months=2,days=1,hours=6)my_model=MyModel(rdfield=rd)my_model.save()Or, alternatively, you can use a string with theISO8601 “format with designators” time interval syntax:fromdateutil.relativedeltaimportrelativedeltamy_model=MyModel(rdfield='P2M1DT6H')my_model.save()For convenience, a standard Pythondatetime.timedeltaobject is
also accepted:fromdatetimeimporttimedeltatd=timedelta(days=62,hours=6)my_model=MyModel(rdfield=td)my_model.save()After afull_clean(), the object will always be converted to a
_normalized_relativedeltainstance.  It is highly recommended
you use thedjango-fullcleanapp to always forcefull_clean()onsave(), so you can be
sure that after asave(), your fields are both normalized
and validated.Limitations and pitfallsBecause this field is backed by anINTERVALcolumn, it neither
supports the relativeweekday,leapdays,yeardayandnlyeardayarguments, nor the absolute argumentsyear,month,day,hour,secondandmicrosecond.Themicrosecondsfield is converted to a fractionalsecondsvalue, which might lead to some precision loss due to floating-point
representation.Theweeksfield 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 thedaysfield 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 theweeksproperty.Support for databases other than PostgreSQL is limited.For consistency reasons, when a relativedelta object is assigned to a
RelativeDeltaField, it automatically callsnormalized()onfull_clean.  This ensures that the database representation is as
similar to the relativedelta as possible (for instance, fractional
days are always converted to hours).