所有
对于我来说,是否有一种直接的方式来显示一个使用modelchoicefield的表单来保存尚未保存的模型?
class Foo(models.Model):
name = models.CharField(max_length=42)
class Bar(models.Model):
name = models.CharField(max_length=42)
foo = models.ForeignKey("Foo",blank=True,null=True)
class BarForm(ModelForm):
class Meta:
model = Bar
pass
def create_new_bar(request):
foos = [Foo(name='foo1'), Foo(name='foo2'), Foo(name='foo3')]
bar = Bar(name='bar',foo=foos[0])
form = BarForm(instance=bar)
return render_to_response('bar_template.html',{"form" : form},context_instance=RequestContext(request))
但是在表单中呈现的“select”小部件具有空内容。据推测,这是因为没有任何东西可以将查询集绑定到Bar的ForeignKey to Foo使用的ModelChoiceField。 (因为“foos”中没有任何内容已保存,因此数据库中不存在。)
除了编写自定义的formfield / widget之外,还有其他方法可以解决这个问题吗?
感谢。
答案 0 :(得分:1)
Foo
不会有pks。所以没有办法可行。表单需要知道Foo
的pk。你真的只需要先保存它们。 django如何知道哪一个在回发表格时是哪一个? IGNORE ANWWER BELOW。
我认为您可以更改字段上的choices
变量。你需要在表格中。因此,将Foo
的列表传递给表单的init。像这样:
class BarForm(ModelForm):
class Meta:
model = Bar
def __init__(self, foo_list, *args, **kwargs):
super(BarForm, self).__init__(*args, **kwargs)
self.fields['foo'].choices = foo_list
然后在视图中:
foos = [Foo(name='foo1'), Foo(name='foo2'), Foo(name='foo3')]
bar = Bar(name='bar', foo=foos[0])
form = BarForm(foos, instance=bar)
我知道我以前做过这样的事情。我只是记不起确切的方式。这样的方法应该有用。
答案 1 :(得分:1)
您可以使用预定义的选项向BarForm
添加其他字段 - 例如fooempty
。如果Foo
表为空,将显示该字段。试试这个(未经测试):
class BarForm(ModelForm):
FOO_CHOICES = (
(0, 'Choice1'),
(1, 'Choice2'),
(2, 'Choice3'),
)
fooempty = forms.ChoiceField(required=False, label='lbl', choices=FOO_CHOICES)
class Meta:
model = Bar
def __init__(self, *args, **kwargs):
super(BarForm, self).__init__(*args, **kwargs)
if self.fields['foo'].queryset.count(): # Foo empty?
self.fields['fooempty'].widget = forms.HiddenInput()
else:
self.emptyflag
self.fields['foo'].widget = forms.HiddenInput()
def save(self, commit=True):
bar = super(BarForm, self).save(commit=False)
if self.emptyflag:
bar.foo_id = self.cleaned_data['fooempty']
bar.save()
return bar