来自: 糊糊(神之码农) 2010-03-29 02:09:26
今天偶然发现一个问题:django对DateField的处理有点问题,可能是python本身的问题,具体是谁的问题我还不太清楚
简单点说吧
定义一个model:
class Note(models.Model):
user = models.ForeignKey(User,editable=False)
pub_date = models.DateField('date published',blank=True,default=datetime.datetime.now().date())
title = models.CharField(max_length=120,null=True,blank=True)
content = models.TextField()
class Meta:
ordering = ('-pub_date',)
verbose_name = _('Note')
verbose_name_plural = _('Notes')
get_latest_by = 'pub_date'
def get_absolute_url(self):
return "/note/%s/" % str(self.id)
def __unicode__(self):
return self.title
--------------------------
然后在forms.py中定义:
class NoteForm(forms.ModelForm):
pub_date = forms.CharField(label=_("pub_date"))
class Meta:
model = Note
exclude = ('user')
----------------------------------
在Views。py中定义add_note
@login_required
@render_to('note/note_form.html')
def add_note(request):
if request.method == 'POST':
form = NoteForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
instance.save()
return HttpResponseRedirect(reverse("note_list"))
else:
form = NoteForm()
return locals()
---------------------------
note_form.html:
{% block content %}
<h2>添加/修改 笔记</h2>
<form method="POST">
<table>
{{form.as_table}}
</table>
<input type="submit" value="{% trans "Save" %}">
</form>
{% endblock %}
------------------------
首先,第一个问题就是admin中添加一个note的时候,pub_date直接就显示了2010-3-28,但是在前端的时候确是空白
第二个问题就是,直接修改了计算机的电脑日期之后,比如修改为2010-3-30,也就是说把时间改到后天,admin中的pub_date还是保持为2010-3-28,没有变成2010-3-30,这个问题,我觉得可能django的manage.py runserver 的时候导入的datetime这个模块的时间保存在内存中不变了。
DDT-holy解答说:
models.DateField('date published',blank=True,default=datetime.datetime.now().date()) 你这种默认直的方式有问题
默认值要定义成callable的,否则模块一旦加载,时间就不变了
我说:那你说的callable要怎么弄啊
DDT-holy解答说:
default=datetime.datetime.now
去掉()
models.DateField('date published',blank=True,default=datetime.datetime.now().date())
--
我 之所以弄成datefield,是因为我还用了个jquery的日期选择模块
就是单击日期输入框,蹦出日期的选择widget,它初始化的时候要求2010-3-28的日期形式,要是用now的话,就会出错
我要取的是date,
是这样的,我是给个初始值而已
holy,那models.DateField('date published',blank=True,default=datetime.datetime.now.date) 行不行啊
DDT-holy答:
不行 now是函数 不是模块
就用datetime.datetime.now就行了你是datefield,它会自动截断的
当然,如果直接在view中处理的话,就不会有这2个问题了
@login_required
@render_to('note/note_form.html')
def add_note(request):
if request.method == 'POST':
form = NoteForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
instance.save()
return HttpResponseRedirect(reverse("note_list"))
else:
form = NoteForm(initial={'pub_date':datetime.datetime.now().date()})
return locals()
这个initial,不仅初始化的时候给出日期,而且,在不重启django服务器的时候修改服务器时间,也一样可以显示修改后的日期。
我把日期弄成2010-3-31了,但是按照holy说的,
models.DateField('date published',blank=True,default=datetime.datetime.now)
后台admin可以随服务器时间变更而改变了,但是出现的格式是 2010-03-31 00:06:29,也就是说没有像holy说的那样自动截断为Date,而是Datetime。
同时,前台的pub_date还是没有出现初始值。
既然在models中定义了default值,为什么前台就是不出现默认值呢?
后来,检查forms.py中的定义,发现
class NoteForm(forms.ModelForm):
# 注释掉下面行就行了
#pub_date = forms.CharField(label=_("pub_date"))
class Meta:
model = Note
exclude = ('user')
注释了NoteForm中的pub_date的重新定义之后,前台出现默认值了,但是还是2010-03-29 00:12:01格式,并且不能随服务器时间变更而改变。
holy解答说:保存的时候会截断
现在你知道我把pub_date = models.DateField('date published',blank=True,default=datetime.datetime.now().date()) 这样定义的原因了吧。主要是那个jquery的日期选择,不能根据2010-03-29 00:12:01的日期时间格式初始化,所以,我的解决方法还是又在views.py 中的add_note 中使用form = NoteForm(initial={'pub_date':datetime.datetime.now().date()}) 来解决这个问题
holy,我试了好久,发现default=datetime.datetime.now().date,也是你说的callable的,而且是可以用的,默认得到的是日期