django 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", который отображается в форме, имеет пустое содержимое. Предположительно, это связано с тем, что нечего связывать набор запросов для ModelChoiceField, который использует ForeignKey Bar для Foo. (Поскольку ничего в "foos" не было сохранено и поэтому не существует в базе данных).
Есть ли другой способ справиться с этим помимо написания настраиваемого поля формы / виджета?
Благодарю.
2 ответа
Вы можете добавить дополнительное поле к 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
РЕДАКТИРОВАТЬ: на самом деле, теперь, когда я думаю об этом. Те Foo
с не будет пкс. Так что нет никакого способа, который когда-либо мог бы работать. Форма должна знать ПК о Foo
s. Вам действительно нужно сначала сохранить их. Как django узнает, кто из них отправляет обратно форму? Игнорировать ответ ниже.
Я думаю, что вы можете изменить choices
переменная на поле. Вам нужно будет это в форме. Так что передайте список Foo
с инициалом формы. Что-то вроде этого:
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)
Я знаю, что сделал что-то подобное раньше. Я просто не могу вспомнить точный путь. Что-то вроде этого подхода должно работать, хотя.