Hi Bobby,
I'm not sure what you mean by "fields don't allow built-in defaults". While
it's true that Django's DateField (for example) doesn't have a built-in
default, here's[1] a custom field with a built-in default:
class MyDateField(models.DateField):
EPOCH = date(1970, 1, 1)
def __init__(self, *args, **kw):
kw.setdefault('default', self.EPOCH)
super(MyDateField, self).__init__(*args, **kw)
I use kw.setdefault so that the default can still be overridden by the
definition of a specific field.
Did you mean something else?
Shai.
[1] Caveat Lector: Untested code. I'd be quite surprised if it doesn't work.
On Tuesday 16 June 2015 01:18:07 Bobby Mozumder wrote:
> > On Jun 15, 2015, at 1:42 PM, Rick van Hattem (wolph) <[email protected]>
> > wrote:
> >
> > While I understand the rationale, it's not really possible due to the
underlying Python object:
> > >>> import datetime
> > >>> datetime.date()
> >
> > Traceback (most recent call last):
> > File "<stdin>", line 1, in <module>
> >
> > TypeError: Required argument 'year' (pos 1) not found
> >
> > >>> datetime.datetime()
> >
> > Traceback (most recent call last):
> > File "<stdin>", line 1, in <module>
> >
> > TypeError: Required argument 'year' (pos 1) not found
>
> A custom Django field would either assign initial values to classes that
> need it, or use classes that have their own initial values. The point is
> that the class itself should always exist in the field.
>
> > Note that you can easily support it by having something like this:
> >
> > class Question(models.Model):
> > pub_date = models.DateField(default=datetime.date.today, blank=True)
>
> Right. I’m trying to avoid this situation, as this adds a lot of code - I
> have dozens of custom fields instantiated hundreds of times in an app,
> with a lot of initialization data each. It also requires the knowledge of
> which internal class that the field uses. So, I have a common get/set
> interface for each custom field, so I don’t need to know which class that
> a field uses, as long as I interface with it properly.
>
> -bobby
>
> > ~wolph
> >
> > On Monday, June 15, 2015 at 7:52:13 AM UTC+2, Bobby Mozumder wrote:
> > Hi all,
> >
> > Here’s an issue of usability that if fixed could make usage of custom
> > fields simpler.
> >
> > Right now fields don’t allow a built-in defaults, and you need to
> > explicitly set the default parameter for model fields. The problem is
> > that this adds a ton of boilerplate code.
> >
> > Using the Polls tutorial example, if I do:
> > >>> from polls.models import Question, Choice
> > >>> q = Question()
> >
> > By default it’s always <class 'NoneType’>:
> > >>> type(q.pub_date)
> >
> > <class 'NoneType'>
> >
> > The pub_date should always be a type <class 'datetime.datetime'>. If this
was defined in the model constructor, then we could start to access the
datetime.datetime class immediately, to assign data. If I had a custom
datetime.datetime class, I could possibly do this immediately:
> > >>> q = Question()
> > >>> q.pub_date.month = 11
> > >>> q.pub_date.day = 26
> > >>> q.pub_date.year = 2016
> > >>> q.save()
> >
> > But right it would give the following error:
> > >>> q.pub_date.year = 2016
> >
> > Traceback (most recent call last):
> > File "<console>", line 1, in <module>
> >
> > AttributeError: 'NoneType' object has no attribute 'year'
> >
> > Is this a reasonable request?
> >
> > I’m able to do something like this now with my own custom fields that
> > derive from models.SubfieldBase, but that class is deprecated, and the
> > new 1.8 model initializer doesn’t do this anymore.
> >
> > Thank you,
> >
> > -bobby