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

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

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

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

class Item(models.Model):
    sku = models.CharField(max_length=50)
    description = models.CharField(max_length=200)
    added_by = models.ForeignKey(User)


class ItemForm(ModelForm):
    class Meta:
        model = Item
        exclude = ('added_by')

def new_item_view(request):
    if request.method == 'POST':
        form = ItemForm(request.POST)
        # Validate and save
    else:
            form = ItemForm()
    # Render the view

Может ли класс ItemForm быть повторно использован? Какие изменения потребуются в классе моделей ItemForm или Item? Нужно ли мне писать другой класс, "ItemUpdateForm", для обновления элемента?

def update_item_view(request):
    if request.method == 'POST':
        form = ItemUpdateForm(request.POST)
        # Validate and save
    else:
        form = ItemUpdateForm()

Ответы [ 26 ]

1 голос
/ 02 февраля 2014

Это самый простой способ?

Прямо в коде вида что-то вроде этого:

def resume_edit(request, r_id):
    .....    
    r = Resume.get.object(pk=r_id)
    resume = ResumeModelForm(instance=r)
    .....
    resume.fields['email'].widget.attrs['readonly'] = True 
    .....
    return render(request, 'resumes/resume.html', context)

Работает отлично!

1 голос
/ 26 марта 2018

Для Джанго 1,9 +
Вы можете использовать аргумент «Поля отключен», чтобы отключить поле. например В следующем фрагменте кода из файла forms.py я отключил поле employee_code

class EmployeeForm(forms.ModelForm):
    employee_code = forms.CharField(disabled=True)
    class Meta:
        model = Employee
        fields = ('employee_code', 'designation', 'salary')

Ссылка https://docs.djangoproject.com/en/2.0/ref/forms/fields/#disabled

0 голосов
/ 08 февраля 2018

Я решил эту проблему так:

    class UploadFileForm(forms.ModelForm):
     class Meta:
      model = FileStorage
      fields = '__all__'
      widgets = {'patient': forms.HiddenInput()}

просмотров:

form = UploadFileForm(request.POST, request.FILES, instance=patient, initial={'patient': patient})

Это все.

0 голосов
/ 30 апреля 2015

Я думаю, что лучшим вариантом будет просто включить атрибут readonly в шаблон, отображаемый в <span> или <p>, а не включать его в форму, если он доступен только для чтения.

Формы для сбора данных, а не их отображения. При этом параметры для отображения в виджете readonly и очистки данных POST являются отличным решением.

0 голосов
/ 03 сентября 2018

Если вы работаете с Django ver < 1.9 (1.9 добавил атрибут Field.disabled), вы можете попробовать добавить в форму следующий декоратор __init__ метод:

def bound_data_readonly(_, initial):
    return initial


def to_python_readonly(field):
    native_to_python = field.to_python

    def to_python_filed(_):
        return native_to_python(field.initial)

    return to_python_filed


def disable_read_only_fields(init_method):

    def init_wrapper(*args, **kwargs):
        self = args[0]
        init_method(*args, **kwargs)
        for field in self.fields.values():
            if field.widget.attrs.get('readonly', None):
                field.widget.attrs['disabled'] = True
                setattr(field, 'bound_data', bound_data_readonly)
                setattr(field, 'to_python', to_python_readonly(field))

    return init_wrapper


class YourForm(forms.ModelForm):

    @disable_read_only_fields
    def __init__(self, *args, **kwargs):
        ...

Основная идея заключается в том, что если поле readonly, вам не нужно другое значение, кроме initial.

P.S: не забудьте установить yuor_form_field.widget.attrs['readonly'] = True

0 голосов
/ 24 марта 2015

Если вы используете администратор Django, вот самое простое решение.

class ReadonlyFieldsMixin(object):
    def get_readonly_fields(self, request, obj=None):
        if obj:
            return super(ReadonlyFieldsMixin, self).get_readonly_fields(request, obj)
        else:
            return tuple()

class MyAdmin(ReadonlyFieldsMixin, ModelAdmin):
    readonly_fields = ('sku',)
...