Как отключить поле модели в форме django

У меня есть такая модель:

class MyModel(models.Model):
    REGULAR = 1
    PREMIUM = 2
    STATUS_CHOICES = ((REGULAR, "regular"), (PREMIUM, "premium"))
    name = models.CharField(max_length=30)
    status = models.IntegerField(choices = STATUS_CHOICES, default = REGULAR)

class MyForm(forms.ModelForm):
    class Meta:
        model = models.MyModel

В представлении я инициализирую одно поле и попытаюсь сделать его нередактируемым:

myform = MyForm(initial = {'status': requested_status})
myform.fields['status'].editable = False

Но пользователь может изменить это поле.

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

Ответ 1

Шаг 1: отключите виджет интерфейса

Использовать атрибут HTML readonly:
http://www.w3schools.com/tags/att_input_readonly.asp

Или disabled:
http://www.w3.org/TR/html401/interact/forms.html#adef-disabled

Вы можете ввести произвольные пары значений ключа HTML через свойство widget attrs:

myform.fields['status'].widget.attrs['readonly'] = True # text input
myform.fields['status'].widget.attrs['disabled'] = True # radio / checkbox

Шаг 2. Убедитесь, что поле эффективно отключено на бэкэнд

Отмените свой чистый метод для своего поля, чтобы независимо от ввода POST (кто-то может подделать POST, отредактировать необработанный HTML и т.д.), вы получите значение поля, которое уже существует.

def clean_status(self):
    # when field is cleaned, we always return the existing model field.
    return self.instance.status

Ответ 2

Вы пытались использовать функцию exclude?

что-то вроде этого

class PartialAuthorForm(ModelForm):
class Meta:
    model = Author
    fields = ('name', 'title')

class PartialAuthorForm(ModelForm):
class Meta:
    model = Author
    exclude = ('birth_date',)

Ссылка здесь

Ответ 3

Просто настройте экземпляр виджета для поля состояния:

class MyModel(models.Model):
    REGULAR = 1
    PREMIUM = 2
    STATUS_CHOICES = ((REGULAR, "regular"), (PREMIUM, "premium"))
    name = models.CharField(max_length=30)
    status = models.IntegerField(choices = STATUS_CHOICES, default = REGULAR)

class MyForm(forms.ModelForm):
    status =  forms.CharField(widget=forms.TextInput(attrs={'readonly':'True'}))

    class Meta:
        model = models.MyModel

см.: Документация по Django

Ответ 4

Из django 1.9:

self.fields['whatever'].disabled = True