Monday, May 4, 2015

Re: How to represent a calendar month as a field in django models

On 2015-05-03 14:35, Matthys wrote:
> I posted the question also on stackoverflow:
>
> http://stackoverflow.com/questions/30017229/how-to-represent-month-as-field-on-django-model
>
> The question is for situations where a model instance relates to a
> specific month, but not to a specific day.

If the other suggestions don't work for you, you could store it as a
regular integer field for the number of months. A custom widget
would allow you to create an interface to manage it, and the value
would simply be "years * 12 + months - 1" and to extract the year and
month, you'd use something like

year, month = divmod(mymodel.my_yearmonth_field, 12)
month += 1

It would have the peculiar side-effect that internally the month
would be represented by a value 0..11 instead of 1..12

However, it has the advantage that it's only one field in the
database and compares naturally ("ORDER BY my_yearmonth_field")

You could even fancy it up something like the below.

-tkc

from django.db import models
from django.forms import widgets

class YearMonth(object):
def __init__(self, year, month):
self.year = year
self.month = month

class YearMonthFormField(widgets.Widget):
# for implementation ideas, see
# https://docs.djangoproject.com/en/1.8/_modules/django/forms/extras/widgets/#SelectDateWidget
pass

class YearMonthField(models.IntegerField):
description = "A field for managing year+month without dates"
def __init__(self, *args, **kwargs):
super(YearMonthField, self).__init__(*args, **kwargs)
def to_python(self, value):
if isinstance(value, YearMonth):
return value
if value is None:
return value
year, month = divmod(value, 12)
return YearMonth(year, month + 1)
def from_db_value(self, value, expression, connection, context):
return self.to_python(value)
def get_prep_value(self, value):
return value.year * 12 + value.month - 1
def formfield(self, **kwargs):
defaults = {'form_class': YearMonthFormField}
defaults.update(kwargs)
return super(YearMonthField, self).formfield(**defaults)

class MyModel(models.Model):
my_yearmonth_field = YearMonthField()

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/20150504120929.78c21193%40bigbox.christie.dr.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment