L Lawliet
L Lawliet

Reputation: 2635

How to customize Django model's field.value_to_string(self) for datetime field

Let's say I have a model

class Job(Model):
     created_on = DateTimeField(_("Created On"), auto_now=True, editable=False)
     name = CharField(_("Name"), max_length=300, blank=False)

Now I am trying to aggregate all fields with their verbose name and value to display it in a template.

My aggregating function:

def get_fields(self):
    result = []
    for field in Job._meta.fields:
        result.append((field.name, field.verbose_name, field.value_to_string(self)))

This gives me the values as string properly, however for a datetime field, I end up with a dumb unformatted string like 2021-02-13T22:39:47.561045+00:00 I really don't want to check and modify the value in some way by specifically checking for the particular field as that is the whole point of my get_field function

I feel any of the following should work fine for me:

  1. Somehow provide the default format to use when calling value_to_string()
  2. Get a proper dateTime object instead, in which case the value should show up fine on the template
  3. Get field type and then instead of calling value_to_string() I manually convert the string to this type (This seems feasible from what I see but feels too hacky of a solution)

Upvotes: 1

Views: 1463

Answers (2)

L Lawliet
L Lawliet

Reputation: 2635

Here is what worked for me:

field.value_from_object(self)

instead of

field.value_to_string(self)

The advantage is the return value is an object which is solution(2) for me. In this case since the object is of the proper type, it got displayed properly!

Upvotes: 1

SDRJ
SDRJ

Reputation: 540

@L Lawliet- Does something like this work. You can add it as models method.

def get_formatted_date(self):
        return self.created_on.strftime("%Y-%m-%d %H:%M:%S")

Alternative approach - source Formatting DateTimeField in Django

class CustomDateTimeField(models.DateTimeField):
    def value_to_string(self, obj):
        val = self.value_from_object(obj)
        if val:
            val.replace(microsecond=0)
            return val.isoformat()
        return ''

in your model

   created_on = CustomDateTimeField(auto_now_add=True)

Upvotes: 1

Related Questions