I am storing dates as an integer field in the format YYYYMMDD, where month or day is optional.
I have the following function for formatting the number:
def flexibledateformat(value):
import datetime, re
try:
value = str(int(value))
except:
return None
match = re.match(r'(\d{4})(\d\d)(\d\d)$',str(value))
if match:
year_val, month_val, day_val = [int(v) for v in match.groups()]
if day_val:
return datetime.datetime.strftime(datetime.date(year_val,month_val,day_val),'%b %e, %Y')
elif month_val:
return datetime.datetime.strftime(datetime.date(year_val,month_val,1),'%B %Y')
else:
return str(year_val)
Which results in the following outputs:
>>> flexibledateformat(20100415)
'Apr 15, 2010'
>>> flexibledateformat(20100400)
'April 2010'
>>> flexibledateformat(20100000)
'2010'
So I’m wondering if there’s a function I can add under the model field class that would automatically call flexibledateformat.
So if there’s a record
r = DataRecord(name=’foo’,date=20100400)
when processed in the form the value would be 20100400 but when output in a template using {{ r.date }} it shows up as “April 2010”.
Further clarification
I do normally use datetime for storing date/time values. In this specific case, I need to record non-specific dates: “x happened in 2009″, “y happened sometime in June 1996″.
The easiest way to do this while still preserving most of the functionality of a date field, including sorting and filtering, is by using an integer in the format of yyyymmdd. That is why I am using an IntegerField instead of a DateTimeField.
This is what I would like to happen:
- I store what I call a “Flexible
Date” in aFlexibleDateFieldas an
integer with the formatyyyymmdd. - I render a form that includes a
FlexibleDateField, and the value
remains an integer so that functions
necessary for validating it and
rendering it in widgets work
correctly. - I call it in a template,
as in {{ object.flexibledate }} and
it is formatted according to the
flexibledateformat rules:20100416
-> April 16, 2010;20100400-> April 2010;20100000-> 2010. This
also applies when I’m not calling it
directly, such as when it’s used as
a header in admin
(http://example.org/admin/app_name/model_name/).
I’m not aware if these specific things are possible.
Also
I have already written a template filter that can perform this function —
({{object.flexibledate|flexibledateformat}}) —
but I’d rather not have to call the filter every time I want to output one of these values. Except when outputting the form, I pretty much never want to see the number.
I think the most djangoish way of accomplishing a similar effect would be to define a custom method on a model:
You can use it in a template like this:
I also wonder why are you using an IntegerField instead of a native DateTimeField.
Update: You can still use the custom method as an option for
list_displayin Django Admin. If you want the column header to say something else then simply the method’s name use the “short_description” option, like this:and then you just use it the same way you would use an ordinary field: