tags:

views:

315

answers:

4

Hello. I have such db model:

from datetime import datetime    

class TermPayment(models.Model):
    dev_session = models.ForeignKey(DeviceSession, related_name='payments')
    user_session = models.ForeignKey(UserSession, related_name='payment')
    date = models.DateTimeField(default=datetime.now(),blank=True)
    sum = models.FloatField(default=0)
    cnt = models.IntegerField(default=0)

    class Meta:
        db_table = 'term_payments'
        ordering = ['-date']

and here new instance is added:

# ...
tp = TermPayment()
tp.dev_session = self.conn.session # device session hash
tp.user_session = self.session # user session hash
tp.sum = sum
tp.cnt = cnt 
tp.save()

But I've a problem: all records in database have the same value in date field - the date of the first payment. After server restart - one record have new date and others have the same as the first. It's look like some data cache is used but I can't find where.

database: mysql 5.1.25

django v1.1.1

+10  A: 

it looks like datetime.now() is being evaluated when the model is defined, and not each time you add a record.

Django has a feature to accomplish what you are trying to do already:

date = models.DateTimeField(auto_now_add=True, blank=True)

or

date = models.DateTimeField(default=datetime.now, blank=True)

The difference between the second example and what you currently have is the lack of parentheses. By passing datetime.now without the parentheses, you are passing the actual function, which will be called each time a record is added. If you pass it datetime.now(), then you are just evaluating the function and passing it the return value.

More information is available at Django's model field reference

Carson Myers
**important note**: using auto_now_add renders the field un-editable in the admin
Jiaaro
+3  A: 

From the documentation on the django model default field:

The default value for the field. This can be a value or a callable object. If callable it will be called every time a new object is created.

Therefore following should work:

date = models.DateTimeField(default=datetime.now,blank=True)
mykhal
+2  A: 

The datetime.now() is evaluated when the class is created, not when new record is being added to the database.

To achieve what you want define this field as:

date = models.DateTimeField(auto_now_add=True)

This way the date field will be set to current date for each new record.

Bartosz
+1  A: 

From the Python language reference, under Function definitions:

Default parameter values are evaluated when the function definition is executed. This means that the expression is evaluated once, when the function is defined, and that that same “pre-computed” value is used for each call.

Fortunately, Django has a way to do what you want, if you use the auto_now argument for the DateTimeField:

date = models.DateTimeField(auto_now=True)

See the Django docs for DateTimeField.

ars