Как показать скрытое автозаполнение в django formset - PullRequest
2 голосов
/ 22 мая 2009

Автополе Django при отображении с использованием набора форм по умолчанию скрыто. Как лучше всего это показать?

На данный момент модель объявлена ​​как

class MyModel:
   locid = models.AutoField(primary_key=True)
   ...

Когда это отрисовывается с использованием форм-наборов Django,

class MyModelForm(ModelForm):
  class Meta:
    model = MyModel
    fields = ('locid', 'name')

отображается на странице как

<input id="id_form-0-locid" type="hidden" value="707" name="form-0-locid"/>

Спасибо.


Редактировать

Я создаю форму, как это -

LocFormSet = modelformset_factory(MyModel) 
pformset = LocFormSet(request.POST, request.FILES, queryset=MyModel.objects.order_by('name')) 

Второе редактирование

Похоже, я не использую класс пользовательской формы, который я там определил, поэтому вопрос нуждается в небольшом изменении.

Как мне создать набор форм из пользовательской формы (которая будет отображать скрытое поле), а также использовать пользовательский набор запросов?

В настоящее время я могу либо наследовать от класса BaseModelFormSet и использовать пользовательский набор запросов, либо я могу использовать класс ModelForm для добавления настраиваемого поля в форму . Есть ли способ сделать оба с помощью formset?


Третье редактирование

Я сейчас использую,

class MyModelForm(ModelForm):
  def __init__(self, *args, **kwargs):
    super(MyModelForm, self).__init__(*args, **kwargs)
    locid = forms.IntegerField(min_value = 1, required=True)
    self.fields['locid'].widget.attrs["type"] = 'visible'
    self.queryset = MyModel.objects.order_by('name')
  class Meta:
    model = MyModel
    fields = ('locid', 'name')

LocFormSet = modelformset_factory(MyModel, form = MyModelForm)
pformset = LocFormSet()

Но это все еще не

  • Показать locid
  • Использовать пользовательский запрос, который был указан.

Ответы [ 4 ]

2 голосов
/ 22 мая 2009

Попробуйте изменить тип поля по умолчанию:

from django import forms
class MyModelForm(ModelForm):
  locid = forms.IntegerField(min_value=1, required=True)
  class Meta:
    model = MyModel
    fields = ('locid', 'name')

РЕДАКТИРОВАТЬ: Протестировано и работает ...

1 голос
/ 22 мая 2009

Как вы говорите, вы не используете пользовательскую форму, которую вы определили. Это потому, что вы нигде не передаёте его, поэтому Джанго не может об этом знать.

Решение простое - просто передайте пользовательский класс формы в modelformset_factory:

LocFormSet = modelformset_factory(MyModel, form=MyModelForm) 

Редактировать в ответ на обновление 3:

Во-первых, у вас есть переопределение для locid в неправильном месте - оно должно быть на уровне класса, а не внутри __init__.

Во-вторых, помещение набора запросов в форму вообще ничего не изменит - формы не знают о наборах запросов. Вы должны вернуться к тому, что вы делали раньше, передав его в качестве параметра при создании экземпляра набора форм. (В качестве альтернативы вы можете определить пользовательский набор форм , но это выглядит как перебор.)

class MyModelForm(ModelForm):
    locid = forms.IntegerField(min_value=1, required=True)

    def __init__(self, *args, **kwargs):
        super(MyModelForm, self).__init__(*args, **kwargs)
        self.fields['locid'].widget.attrs["type"] = 'visible'
    class Meta:
        model = MyModel
        fields = ('locid', 'name')

LocFormSet = modelformset_factory(MyModel, form = MyModelForm)
pformset = LocFormSet(request.POST, request.FILES,
                      queryset=MyModel.objects.order_by('name')))
0 голосов
/ 12 августа 2009

Причина, по которой автоматическое поле скрыто, заключается в том, что BaseModelFormSet и BaseInlineFormSet переопределяют это поле в add_field. Способ исправить это - создать свой собственный набор форм и переопределить add_field без вызова super. Также вам не нужно явно определять первичный ключ.

Вы должны передать набор форм в modelformset_factory:

    LocFormSet = modelformset_factory(MyModel, 
           formset=VisiblePrimaryKeyFormSet)

Это в классе formset:

from django.forms.models import BaseInlineFormSet, BaseModelFormSet, IntegerField
from django.forms.formsets import BaseFormSet

class VisiblePrimaryKeyFormset(BaseModelFormSet):
    def add_fields(self, form, index):
        self._pk_field = pk = self.model._meta.pk
        if form.is_bound:
            pk_value = form.instance.pk
        else:
            try:
                pk_value = self.get_queryset()[index].pk
            except IndexError:
                pk_value = None
        form.fields[self._pk_field.name] = IntegerField( initial=pk_value,
                 required=True) #or any other field you would like to display the pk in
        BaseFormSet.add_fields(self, form, index) # call baseformset which does not modify your primary key field
0 голосов
/ 24 мая 2009

Хорошо, ни один из вышеперечисленных подходов для меня не сработал. Наконец-то я решил эту проблему со стороны шаблона.

  • Есть поданный тикет (http://code.djangoproject.com/ticket/10427),, который добавляет параметр "значение" к переменной шаблона для формы. Например, он позволяет,

    {{form.locid.value}}

будет показано. Это доступно в виде патча, который можно установить в SVN-версии django, используя «patch -p0 file.patch»

  • Помните, что переменная {{form.locid.value}} будет использоваться в сочетании с невидимой формой - в противном случае операции отправки и сохранения для набора форм завершатся сбоем.

  • Это Не то же самое, что {{form.locid.data}} - как объяснено в билете, указанном выше.

...