简体   繁体   中英

How to reproduce native template date formatting with value_to_string in Django

I am trying to write a module which allows me to specify which fields should be displayed in a FieldList directly in the model, in order to be able to use generic template for all the models.

So, in the template for the generic list, I don't know what fields have to be displayed. Using templatetags (I know, it's a bit ugly), I am finally able to display the list with the corresponding values, but I have to use the function value_to_string , as described here :

@register.simple_tag
def get_value_field(instance, field):
    """
    Returns the value of a field for an instance.
    """
    return field.value_to_string(instance)

And in the template :

{% with object_list|get_list_fields as field_list %}
    [...]
        {% for field in field_list %}
        <td> {% get_value_field object field %} </td>
        {% endfor %}

Everything is working, except that I don't understand why value_to_string (which uses isoformat() , see http://fossies.org/dox/Django-1.6.5/django_2db_2models_2fields_2____init_____8py_source.html#l00806 ) and the default template formatting behave differently, as {{ object.date_begin }} displays "11 août 2014" (I'm French) although the {% get_value_field object field %} gives me the isoformat() "2014-08-11".

What am I doing wrong ?

I may use the following code to get the python date and then format it, but I am sure there is a better way to do this.

@register.simple_tag
def get_value_field(instance, field):
    """
    Returns the value of a field for an instance.
    """

    # Cas particuliers pour l'affichage
    if isinstance(field, django.db.models.fields.DateField):
        return field._get_val_from_obj(instance).[...] # Format date to the same format here

    return field.value_to_string(instance)

The behavior is different because your custom tag is returning a raw string, whereas {{ object.date_begin }} returns a date object which the template engine then turns into a string. With localization turned on, which it is by default, date formats are localized.

I think you can get the same behavior in your template tag by importing and calling django.utils.formats.localize on the value of the field from _get_val_from_obj , probably with a little post-processing to catch any non-string values looked up that localize does not handle like model instances. localize returns the value unchanged if it's not a value it can handle, so you can check for non-string return values from localize rather than checking for date results from _get_val_from_obj - I think think that's a little cleaner.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM