В форме Django как сделать поле доступным только для чтения (или отключенным), чтобы его нельзя было редактировать?

Хотя следует избегать явного использования оператора равенства случая, Regexp#=== выглядит очень чистым:

def integer?(str)
  /\A[+-]?\d+\z/ === str
end

integer? "123"    # true
integer? "-123"   # true
integer? "+123"   # true

integer? "a123"   # false
integer? "123b"   # false
integer? "1\n2"   # false

394
задан phoenix 30 July 2016 в 01:58
поделиться

3 ответа

Как указано в этот ответ , Django 1.9 добавил атрибут Field.disabled:

отключенный булев аргумент, когда установлено на Правда, отключает поле формы с помощью отключенного HTML-атрибута так, чтобы это won’t быть доступным для редактирования пользователями. Даже если пользователь вмешается в значение field’s, отправленное серверу, оно будет проигнорировано в пользу значения от form’s исходных данных.

С Django 1.8 и ранее, чтобы отключить запись на виджете и предотвратить злонамеренные взломы POST необходимо вычистить вход в дополнение к установке эти readonly атрибут на поле формы:

class ItemForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(ItemForm, self).__init__(*args, **kwargs)
        instance = getattr(self, 'instance', None)
        if instance and instance.pk:
            self.fields['sku'].widget.attrs['readonly'] = True

    def clean_sku(self):
        instance = getattr(self, 'instance', None)
        if instance and instance.pk:
            return instance.sku
        else:
            return self.cleaned_data['sku']

Или, замените if instance and instance.pk другим условием, указывающим, что Вы редактируете. Вы могли также установить атрибут disabled на поле ввода, вместо readonly.

Эти clean_sku функция гарантирует, что эти readonly значение не будет переопределено POST.

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

390
ответ дан Saransh Singh 30 July 2016 в 01:58
поделиться

Установка, ТОЛЬКО ДЛЯ ЧТЕНИЯ на виджете только, делает вход в браузере только для чтения. Добавление clean_sku, который возвращает instance.sku, гарантирует, что значение поля не изменится на уровне формы.

def clean_sku(self):
    if self.instance: 
        return self.instance.sku
    else: 
        return self.fields['sku']

Этот способ, которым можно использовать модель (неизмененное сохранение) и постараться не получать поле, потребовал ошибки.

93
ответ дан SaeX 30 July 2016 в 01:58
поделиться

To make this work for a ForeignKey field, a few changes need to be made. Firstly, the SELECT HTML tag does not have the readonly attribute. We need to use disabled="disabled" instead. However, then the browser doesn't send any form data back for that field. So we need to set that field to not be required so that the field validates correctly. We then need to reset the value back to what it used to be so it's not set to blank.

So for foreign keys you will need to do something like:

class ItemForm(ModelForm):

    def __init__(self, *args, **kwargs):
        super(ItemForm, self).__init__(*args, **kwargs)
        instance = getattr(self, 'instance', None)
        if instance and instance.id:
            self.fields['sku'].required = False
            self.fields['sku'].widget.attrs['disabled'] = 'disabled'

    def clean_sku(self):
        # As shown in the above answer.
        instance = getattr(self, 'instance', None)
        if instance:
            return instance.sku
        else:
            return self.cleaned_data.get('sku', None)

This way the browser won't let the user change the field, and will always POST as it it was left blank. We then override the clean method to set the field's value to be what was originally in the instance.

53
ответ дан 22 November 2019 в 23:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: