Подтвердить что ты не робот

Почему поля Django для чтения доступны только для чтения?

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

Рассмотрите приложение для учителей, в котором учитель хотел бы иметь возможность вводить все ученики (обратите внимание на множественные ученики) с помощью единого ПОДАЧИ. Модель modelset может перебирать все студентские классы таким образом, чтобы имя студента было доступно только для чтения, а класс - редактируемое поле. Мне нравится сила и удобство проверки ошибок и сообщения об ошибках, которые вы получаете с помощью modelformset, но оставляя имя студента, редактируемое в таком составе, безумным.

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

4b9b3361

Ответ 1

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

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

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

Это невозможно в django.

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

Ответ 2

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

fooobar.com/questions/20401/...

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

{{ form.instance.LastName }}

Ответ 3

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

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) 

Ответ 4

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

Я объединяю объекты-ученики и набор форм для классов класса class_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 formet можно узнать здесь http://whoisnicoleharris.com/2015/01/06/implementing-django-formsets.html