开发者

Is there a way to customize how the value for a custom Model Field is displayed in a template?

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:

>>> fle开发者_Python百科xibledateformat(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:

  1. I store what I call a "Flexible Date" in a FlexibleDateField as an integer with the format yyyymmdd.
  2. 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.
  3. 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:

class Model(models.Model):
    date = models.IntegerField()
    ...

    def flexibledate(self):
        return flexibledateformat(self.date)

You can use it in a template like this:

{{ r.flexibledate }}

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_display in 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:

class Model(models.Model):
    date = models.IntegerField()
    ...

    def flexibledate(self):
        return flexibledateformat(self.date)
    flexibledate.short_description = 'Date'

and then you just use it the same way you would use an ordinary field:

class YourModelAdmin(admin.ModelAdmin):
    list_display = ('title', 'flexibledate')
admin.site.register(YourModel, YourModelAdmin)


That is not necesary, read about humanize and filtertag time

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜