在Django中以不同格式传递日期时间给models.DateTimeField?

7 投票
4 回答
15264 浏览
提问于 2025-04-17 06:31

我有一个模型,看起来像这样:

class Post(models.Model):
    id = models.IntegerField(unique=True, primary_key=True)
    title = models.CharField(max_length=150, blank=True)
    created = models.DateTimeField(blank=True)
    ...

我需要把一些数据填入数据库。我得到的数据是一个简单的json字符串(没有嵌套),所以我的工作相对简单,也就是说:

mydict = json.loads(jsonstr)
mypost = Post(**mydict) 
mypost.save()

不过有一个问题,就是日期时间的格式是“YYYY-MM-DDThh:mm:ss+zzzz”(例如:"created" : "2011-11-17T09:21:31+0000"),这个格式会让上面的代码出错。

我知道forms.DateTimeFieldinput_formats这个选项。有没有办法让DateTimeField接受这种格式呢?

4 个回答

1

我认为DateTimeField需要的是不带时区的日期时间,所以你需要去掉那个(+zzzz)的部分。

naive = dt.replace(tzinfo=None)

这只适用于Python 2.x版本。

3

你可以使用一个叫做 ModelForm 的东西,并且可以修改 created 这个表单字段,而不是直接去改你的模型。

大概是这样的:

from django.forms import ModelForm

class PostForm(ModelForm):
    created = forms.DateTimeField(input_formats=('%Y-%m-%dT%H:%M:%S+0000',))
    class Meta:
        model = Post

mydict = ...

form = PostForm(mydict)
if not form.is_valid():
    # handle appropriately for your app
    raise Exception

instance = form.save() # or use 'commit=False' if you don't want to save to DB

不过,我觉得 strptime 可能不支持GMT时区偏移,所以我在 input_format 中直接写死了这个值。如果你想自己处理这个字段的数据,可以考虑重写它的 'clean' 方法。

7

你可以通过创建一个叫做 ConvertingDateTimeField 的新类来扩展 DateTimeField,并把值转换成合适的格式:

class ConvertingDateTimeField(models.DateTimeField):

    def get_prep_value(self, value):
        return str(datetime.strptime(value, FORMAT_STRING))

然后用 ConvertingDateTimeField 来替换掉 models.DateTimeField。

其实如果你看看 DateTimeField 是怎么创建日期时间对象的,可能会找到更好的方法。

撰写回答