You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django 1.10:子类如何手动设置父类auto_now_add属性的created_at字段

How to Manually Update created_at in a Django Subclass

Let's break down how to properly override the save method in your Item class to set created_at manually, since the base field uses auto_now_add=True which normally locks the value to the first save time.

The Core Issue

When a field has auto_now_add=True, Django automatically sets it to the current datetime on initial creation and ignores any manual values you try to assign—unless you temporarily bypass this behavior for the specific instance.

Complete Solution Code

Here's the adjusted save method for your Item class, assuming you want to pull created_at from an existing item with the same identifier:

from django.utils import timezone

class BaseModel(models.Model):
    created_at = models.DateTimeField(db_index=True, auto_now_add=True)

class Item(BaseModel):
    title = models.CharField(max_length=200)
    identifier = models.CharField(max_length=15)

    def save(self, *args, **kwargs):
        # Only adjust created_at for new instances (not updates)
        if not self.pk:
            try:
                # Fetch the existing item using your custom queryset
                existing_item = Item.objects.active_and_deleted().get(identifier=self.identifier)
                
                # Temporarily disable auto_now_add to allow manual assignment
                created_at_field = self._meta.get_field('created_at')
                original_auto_now_add = created_at_field.auto_now_add
                created_at_field.auto_now_add = False
                
                # Set created_at to match the existing item
                self.created_at = existing_item.created_at
                
                # Save the instance
                super().save(*args, **kwargs)
                
                # Restore the original auto_now_add setting to avoid breaking other uses
                created_at_field.auto_now_add = original_auto_now_add
            except Item.DoesNotExist:
                # No existing item found—fall back to the default auto_now_add behavior
                super().save(*args, **kwargs)
        else:
            # For existing items, let the base class handle save logic
            super().save(*args, **kwargs)

Key Details to Note

  • Temporary Field Adjustment: We only turn off auto_now_add for the specific instance being saved, so other models inheriting from BaseModel won't be affected.
  • Error Handling: The try/except block ensures we gracefully handle cases where no existing item with the same identifier exists—falling back to the default behavior in that scenario.
  • Create vs Update: We check if not self.pk to target only new instances, since auto_now_add only applies to initial creation anyway.

Alternative: Simplify the Base Model

If you expect to override created_at in multiple subclasses, consider modifying the BaseModel to use default instead of auto_now_add:

class BaseModel(models.Model):
    created_at = models.DateTimeField(db_index=True, default=timezone.now)

This removes the need for temporary field modifications entirely—Django will set the current datetime by default, but you can easily override it in any subclass. The only tradeoff is that created_at will be set when the instance is initialized, not when it's saved, but this is acceptable for most use cases.


内容的提问来源于stack exchange,提问作者user2880391

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:28:15