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

I am storing dates as a whole field in YYYYMMDD format where month or day are optional.

I have the following function to format a 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)

      

This leads to the following outputs:

>>> flexibledateformat(20100415)
'Apr 15, 2010'
>>> flexibledateformat(20100400)
'April 2010'
>>> flexibledateformat(20100000)
'2010'

      

So I am wondering if there is a function that I can add below the model field class that is automatically called flexibledateformat

.

So, if there is an entry r = DataRecord (name = 'foo', date = 20100400), when processed in the form, the value will be 20100400

, but when output to the template using {{ r.date }}

it is displayed as "April 2010".

Further clarifications

I usually use datetime to store date / time values. In this particular case, I need to write down non-specific dates : "x happened in 2009", "y happened in June 1996".

The easiest way to do this, while still retaining most of the functionality of the date field, including sorting and filtering, is to use an integer in the format yyyymmdd

. This is why I am using IntegerField

instead DateTimeField

.

This is what I would like to do:

  • I store what I call "flexible" date in FlexibleDateField

    as an integer with the format yyyymmdd

    .
  • I am submitting a form that includes a FlexibleDateField and the value remains an integer, so that the functions are needed to validate it and render it in the widgets correctly.
  • I call it in the template as in {{object.flexibledate}} and it is formatted according to the flexibledateformat rule: 20100416

    -> April 16, 2010; 20100400

    → April 2010; 20100000

    → 2010. This also applies when I don't name it directly, for example when it is used as a title in the admin ( http://example.org/admin/app_name/model_name/

    ).

I don't know if these specific things are possible.

Also

I've already written a templated filter that can do this - ( {{object.flexibledate|flexibledateformat}}

) - but I wouldn't want to call the filter every time I want to output one of these values. Also, when you render the form, I almost never want to see the number.

0


source to share


2 answers


I think the most djangoish way to achieve a similar effect would be to define a custom method on the model:

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

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

      

You can use it in your template like this:

{{ r.flexibledate }}

      

I am also wondering why you are using IntegerField instead of your own DateTimeField.



Update: You can still use a custom method as an option list_display

in Django Admin. If you want the column heading to say something else, just the method name uses the "short_description" parameter, for example:

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

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

      

and then you just use it like you would a normal field:

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

      

+2


source


This is optional, read humanize and filtertag time



-1


source







All Articles