valid update formularios form example crear django django-models django-forms

django - update - formularios web python



¿Por qué los campos de formulario de solo lectura en Django son una mala idea? (4)

He estado buscando una manera de crear un campo de formulario de solo lectura y cada artículo que he encontrado sobre el tema viene con una declaración de que "esta es una mala idea". Ahora, para una forma individual, puedo entender que hay otras formas de resolver el problema, pero usar un campo de formulario de solo lectura en un conjunto de modelos parece una idea completamente natural.

Considere la posibilidad de una aplicación para el libro de calificaciones del docente, donde el docente le gustaría poder ingresar todas las calificaciones de los estudiantes (tenga en cuenta los estudiantes en plural) con un solo ENVIAR. Un conjunto de modelos podría iterar sobre todas las calificaciones de los estudiantes de tal manera que el nombre del alumno sea de solo lectura y el grado sea el campo editable. Me encanta el poder y la conveniencia de la comprobación de errores y los informes de errores que se obtienen con un conjunto de modelos, pero dejar el nombre del alumno editable en un formset así es una locura.

Dado que el consenso experto de django es que los campos de solo lectura son una mala idea, me preguntaba cuál es la mejor práctica estándar de django para el ejemplo anterior de grado de estudiante.


Al usar un campo deshabilitado, también debe asegurarse de que se llene correctamente si el formulario no valida. Este es mi método, que también se encarga de los intentos maliciosos de cambiar los datos enviados:

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)


La razón por la que no desea hacer esto es porque alguien puede cambiar su campo deshabilitado a habilitado y luego enviar el formulario. Debería cambiar la función de guardar para no insertar los datos "deshabilitados".

La forma estándar de hacer esto es no poner el nombre en una entrada, sino mostrarlo como texto

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

Esto no es posible en django.

Yo digo que si realmente confías en tu base de usuarios para no "meterse" con las cosas, entonces hazlo, pero si es un sitio web público con posibles datos confidenciales, entonces aléjate.


Por lo que puedo ver para su situación, esta es la respuesta ideal:

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

Es decir, simplemente imprima las variables del modelo en la plantilla:

{{ form.instance.LastName }}


para el ejemplo de estudiante / calificación, he encontrado una solución, donde los estudiantes son campos no editables y las calificaciones se pueden editar y actualizar según sea necesario. algo como esto

Estoy combinando objetos de alumnos y formset para calificaciones en la clase grade_edit en view.py usando la función 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 })

Mi plantilla se ve algo como esto

<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>

Puede leer más sobre el formset de Django aquí http://whoisnicoleharris.com/2015/01/06/implementing-django-formsets.html