初始化带有外键和默认值的django.forms.ModelChoiceField
我有一个模型,这个模型里有一个外键值,然后我在这个模型生成的表单中使用了一个叫做 ModelChoiceField 的字段。我想要自动选择用户的 (update_author)。
我尝试了下面的代码,使用了初始值的属性。
这个视图创建了一个表单集,空表单的日期初始化为现在的时间。但是,我还想让 update_author 字段也初始化为某个值,但这并没有成功。即使开发者工具返回了正确的用户(打印出来的),这个用户在列表中还是没有被选中。
怎么才能给一个和外键绑定的 django.forms.ModelChoiceField 初始化一个值呢?
models.py
from django.db import models
import datetime
class Author(models.Model):
name = models.CharField(max_length=255)
email = models.CharField(max_length=255)
def __unicode__(self):
return self.name
class DataReview(models.Model):
comments = models.CharField(max_length=255)
update_author = models.ForeignKey('Author')
creation_date = models.DateTimeField('date data review created')
update_date = models.DateTimeField('date review modified')
def __unicode__(self):
return "%s" % (self.comments)
forms.py 修正
from bamboo.followup.models import *
from django import forms
from django.forms import ModelForm,Form
from django.forms.extras.widgets import SelectDateWidget
import datetime
class DataReviewForm(ModelForm):
def __init__(self, *args, **kwargs):
initial = {
'update_date': datetime.datetime.now(),
'creation_date': datetime.datetime.now(),
'update_author': 1 # not Author.objects.get(id=1)
}
if kwargs.has_key('initial'):
kwargs['initial'].update(initial)
else:
kwargs['initial'] = initial
# Initializing form only after you have set initial dict
super(DataReviewsForm,self).__init__(*args, **kwargs)
self.fields['update_date'].widget.attrs['disabled']=''
self.fields['creation_date'].widget.attrs['disabled']=''
self.fields['update_author'].widget.attrs['disabled'] = ''
class Meta:
model = DataReview
views.py 更新
def review(request):
DataReviewsFormSet = modelformset_factory(DataReview, form=DataReviewsForm)
if request.method == 'POST':
formset = DataReviewSet(request.POST)
if formset.is_valid():
# do something with the formset.cleaned_dat
print 'YOUHOU!'
else:
formset = DataReviewSet()
return render_to_response('followup/runs.html', {
"formset": formset,
})
1 个回答
2
你问的核心问题是,如何为外键字段设置初始值,下面的代码片段可以帮你理解。
要注意的是,当你给外键字段提供初始值时,不需要传递整个对象。只需要传递这个对象的ID或者主键,这样你的问题就解决了。
initial = {
'update_date': datetime.datetime.now(),
'creation_date': datetime.datetime.now(),
'update_author': 1 # not Author.objects.get(id=1)
}
if kwargs.has_key('initial'):
kwargs['initial'].update(initial)
else:
kwargs['initial'] = initial
# Initializing form only after you have set initial dict
super(DataReviewsForm,self).__init__(*args, **kwargs)
self.fields['update_date'].widget = forms.HiddenInput()
self.fields['creation_date'].widget = forms.HiddenInput()
self.fields['update_author'].widget = forms.HiddenInput()
这样做会更简洁。
禁用字段 因为表单在调用构造函数后才会显示“字段小部件”,所以任何更新(比如小部件的覆盖,或者改变小部件的属性)都只能在那之后进行。或者,你也可以在表单字段定义时进行修改,但这不适用于你的情况。简单来说,禁用字段最好是在调用父类构造函数之后进行。