Почему мое исключенное поле все еще появляется в этой форме Django?

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

Вот некоторые отрывки из кода:

# Model
class Info(models.Model):
    completed_by = models.ForeignKey(User, related_name='+')

# Form
class InfoForm(forms.ModelForm):
    class Meta:
        model = Info
        exclude = ('created_by',)  #ETA: added comma to make this a tuple
        widgets = {
            'some_other_field': forms.HiddenInput(),
            'some_other_field2': forms.DateInput(attrs={'readonly': True}),
        }

# View
form = InfoForm(initial={'some_other_field': value}, 
                          prefix='info', instance=info)
return direct_to_template(request, 'myapp/info.html', locals())

# Template
<form class='uniForm' method='POST'>
{% csrf_token %}
<fieldset class='inlineLabels'>{{ form|as_uni_form }}</fieldset>
<input type='submit' name='action' value='Save' />
</form>

Кажется, что это должно быть довольно просто, и я знаю, что я сделал это успешно раньше. Я удалил/воссоздал свою БД и очистил кеш браузера, чтобы быть уверенным, что это не фактор. Я также попытался сделать это поле HiddenInput, как и some_other_field (которое также является полем ForeignKey), но оно все еще отображается в форме.

Есть ли что-то здесь, я не хватает? Как uni_form переопределяет настройку? Если нет, то какие-либо рекомендации относительно того, что я могу найти в отладке, чтобы узнать, где/почему это происходит?

(с использованием Django версии 1.2.7)

Ответ 1

exclude требует кортежа, поэтому вам нужно

# note the extra comma
exclude = ('created_by',)

django выполняет итерацию через exclude, и поскольку строки являются итерируемыми (возвращают каждый символ), это не вызывает ошибки

Ответ 2

Я знаю, что это устарело, но публикуется здесь как ссылка.

Я столкнулся с этой же проблемой, потому что я перегрузил clean_fields() в модели, но не правильно назвал суперкласс.

 class MyModel(models.Model):
    foo = models.BooleanField()    

    # Wrong!  Don't do this!
    def clean_fields(self, exclude=None):
        # Bah!  Forgetting to pass exclude defaults it to None!
        super(MyModel, self).clean_fields()
        if not self.foo:
            raise ValidationError('Ah fooey.')

    # Correct!  Do it this way!
    def clean_fields(self, exclude=None):
        # That better!  Let take a coffee break.  I'm tired.
        super(MyModel, self).clean_fields(exclude)
        if not self.foo:
            raise ValidationError('Ah fooey.')

Ответ 3

Для более старых версий Django существует проблема с исключением немодельных полей, которые вы явно объявляете, например. в классе родительской формы. Добавление следующего в вашу форму init позаботится об этом даже для немодельных полей (см. https://code.djangoproject.com/ticket/8620).

def __init__(self, *args, **kwargs):
    super(MyForm, self).__init__(*args, **kwargs)
    [self.fields.pop(f) for f in self.fields.keys() if f in self.Meta.exclude]