2014-03-15 2 views
1

Все,Джанго modelchoicefield несохранённых модели

Есть ли простой способ для меня, чтобы отобразить форму, которая использует 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)) 

Но виджет «выбрать», который отображается в форме, содержит пустой контент. Предположительно, это связано с тем, что привязать набор запросов к ModelChoiceField, который используется BarK ForeignKey для Foo, нет. (Так как ничего в «foos» не было сохранено и поэтому не существует в базе данных).

Есть ли другой способ справиться с этим, помимо написания пользовательского поля формы/виджета?

Спасибо.

ответ

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 
+0

Да, я делаю что-то вроде этого. Я переопределяю поле формы с помощью ChoiceField в форме _init_fn формы. И я передаю набор вариантов конструктору поля. В методе сохранения формы я сохраню Foo, который соответствует выбранному элементу в поле выбора, а затем установите bar.foo на этот идентификатор. – trubliphone

1

EDIT: на самом деле, теперь, когда я думаю об этом. У тех Foo s не будет pks. Так что нет никакого способа, который мог бы когда-либо работать. Форма должна знать pk Foo s. Вам просто нужно сначала сохранить их. Как django знает, какой из них, когда он возвращает форму? ИГНОРНЫЙ ОТВЕТ НИЖЕ.

Я думаю, вы можете изменить переменную choices на поле. Вам понадобится это в форме. Итак, передайте список Foo s в начало формы. Что-то вроде этого:

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) 

Я знаю, что я сделал что-то подобное раньше. Я просто не могу вспомнить точный путь. Тем не менее, такой подход должен работать.

Смежные вопросы