Почему поля формы только для чтения в Django - плохая идея? - PullRequest
27 голосов
/ 25 мая 2010

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

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

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

Ответы [ 4 ]

25 голосов
/ 25 мая 2010

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

Стандартный способ сделать это - не вводить имя во входные данные, а отображать его как текст

<form>
    <div>
        <label>Name</label>
        <p>Johnny Five</p>
    </div>
    <div>
        ....

Это невозможно в Джанго.

Я говорю, что если вы действительно доверяете своей пользовательской базе, чтобы не «связываться» с вещами, то сделайте это, но если это общедоступный сайт с возможными конфиденциальными данными, тогда держитесь подальше.

10 голосов
/ 10 октября 2014

Насколько я вижу для вашей ситуации, это идеальный ответ:

https://stackoverflow.com/a/2242468/1004781

Т.е. просто напечатайте переменные модели в шаблоне:

{{ form.instance.LastName }}
1 голос
/ 07 мая 2015

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

class MyForm(forms.Form):

    MY_VALUE = 'SOMETHING'
    myfield = forms.CharField(
        initial=MY_VALUE,
        widget=forms.TextInput(attrs={'disabled': 'disabled'})

    def __init__(self, *args, **kwargs):

        # If the form has been submitted, populate the disabled field
        if 'data' in kwargs:
            data = kwargs['data'].copy()
            self.prefix = kwargs.get('prefix')
            data[self.add_prefix('myfield')] = MY_VALUE
            kwargs['data'] = data

        super(MyForm, self).__init__(*args, **kwargs) 
0 голосов
/ 22 апреля 2017

для примера ученика / оценки, я придумала решение, в котором учащиеся не могут редактировать поля, а оценки можно редактировать и обновлять по мере необходимости. как то так

Я комбинирую объекты учащихся и набор форм для оценок в классе grade_edit в view.py с помощью функции zip.

def grade_edit(request, id):
    student = student.objects.get(id=id)
    grades = grades.objects.filter(studentId=id)
    gradeformset = GradeFormSet(request.POST or None)
    if request.POST:
        gradeformset = GradeFormSet(request.POST, request.FILES, instance=student)
        if gradeformset.is_valid():
            gradeformset.save()
            grades = grades.objects.filter(studentId=id)
            return render(request, 'grade_details.html', {'student': student, 'grades': grades})
    else:
        gradeformset = GradeFormSet(instance=student)
        grades = grades.objects.filter(studentId=id)
        zips = zip(grades, gradeformset)
    return render(request, 'grade_edit.html', {'zips': zips, 'student': student, 'gradeformset': gradeformset })

Мой шаблон выглядит примерно так

<table>
         <tr>
     {% for field in gradeformset.forms.0 %}
          {% if not field.is_hidden %}
               <th>{{ field.label }}</th>
          {% endif %}
     {% endfor %}
     </tr>
     {% for f in gradeformset.management_form %}
          {{ f }}
     {% endfor %}
     {% for student, gradeform in zips %}
          <tr>
             {% for hidden in form.hidden_fields %}
                 {{ hidden }}
             {% endfor %}
             <td> {{ student.name }} </td>
             <td> {{ gradeform.gradeA }} </td>
             <td> {{ gradeform.gradeB }} </td>
          </tr>
     {% endfor %}
</table>

Вы можете узнать больше о Django formset здесь http://whoisnicoleharris.com/2015/01/06/implementing-django-formsets.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...