-->

Django custom field to handle datefield with only

2019-08-25 12:49发布

问题:

---------------- EDIT --------------------

I could not succed doing it with Custom Model Field and I had to move on, so actually, I did it the alternative way specified at the end of this post.

Here is a link to a new post exposing the solution.

---------------- END EDIT --------------------

My app displays formsets where users can create objects. Once validated, the formset is displayed again and user can add new objects.

Dates should only be month and year ("%m/%Y").

I could work on the input field (though jquery) to add '01/' in front of the date entered. But after submitting, the field now displays "%d/%m/%Y" (normal).

So, I'm looking for a way to translate input string (ex : 09/2018) to dateField to store in the database, and then a translate this dateField to string when datas are retrieved from database.

I know, I could simply use a form charfield for months and another one for years.

But I would like to keep it as a date object, so, in templates, I could perform date formatting ({{ edu.start_date |date:"D, d M, Y" }})

Django custom model fields sound made for this : Django custom model fields.

I could do something like this in the custom field:

def string_to_date(value):
    value = '01/' + value
    la_date = datetime.strptime(value, "%d/%m/%Y").date()
    return la_date

def date_to_string(la_date_date):
    la_date_str = la_date_date.strftime('%m/%Y')
    return la_date_str

class DateYearMonth(models.DateField):
    def get_prep_value(self, value):
        if value is None:
            return value
        return string_to_date(value)

    def to_python(self, value):
        if value is None:
            return value
        return date_to_string(value)

The form associated (i commented widgets):

class EducationForm(forms.ModelForm):
    start_date =  forms.CharField()
    end_date = forms.CharField()

    class Meta:
        model = Education
        exclude = ("curriculum",)

        #     # les widgets :
       #       widgets = {
        #          'start_date': forms.TextInput(),
        #          'end_date': forms.TextInput(),
#     }

Well, this does not work so far. But I don't even know if I'm heading to the right direction...

EDIT

Actually, maybe I could use simple charfield for month and year and add a model method that would create a date out of it (maybe a @property)... This way, I would keep it simple on the form and be able to format on the templates...

回答1:

You can make the Year an IntegerField and Month (CharField or Integer) and store Year in Months individually is probably the best solution. Below is an example fore Year only(kind of DatetimeField to YearField)

import datetime
    YEAR_CHOICES = []
    for r in range(1980, (datetime.datetime.now().year+1)):
        YEAR_CHOICES.append((r,r))

    year = models.IntegerField(_('year'), choices=YEAR_CHOICES, 
           default=datetime.datetime.now().year)