vistas example clases based basadas django django-forms django-views django-class-based-views

example - listview django



Vistas basadas en la clase Django-UpdateView con dos formularios modelo-una presentaciĆ³n (2)

Tengo una página con una lista de usuarios y me gustaría poder hacer clic en un enlace para actualizar su perfil. Cuando se hace clic en "actualizar", debería poder editar el nombre de usuario, el nombre, el correo electrónico, el número de teléfono, el departamento, etc., en una sola página, utilizando un solo botón de envío. Lo logré utilizando dos formularios, uno para el usuario y otro para la información adicional. ListView, DeleteView y CreateView funcionan perfectamente con estos dos formularios, pero no con UpdateView. No puedo instanciar los dos formularios con datos iniciales.

La pregunta es: ¿cómo instanciar los dos formularios con datos? Sobrescribir self.object? get_form_kwargs? ¿Cuál sería la solución más elegante?

La clase UpdateView está debajo. No estoy buscando una solución de "copiar y pegar", pero tal vez apuntarme en la dirección correcta.

Gracias.

Pablo

El número de teléfono, departamento se define en un modelo llamado Empleado.

class Employee(models.Model): user = models.OneToOneField(User) phone_number = models.CharField(max_length=13, null=True) department = models.CharField(max_length=100)

La plantilla es:

{% extends "baseadmin.html" %} {% load crispy_forms_tags %} {% block content %} <h4>Edit a user</h4> <form action="" method="post" class="form-horizontal"> <legend>Edit a user</legend> {% crispy form %} {% crispy form2 %} <div class="form-actions"> <input type="submit" class="btn btn-primary" value="Save"> <a href="{% url ''client_list'' %}" class="btn">Cancel</a> </div> </form> {% endblock content %}

La clase de vista es:

class ClientUpdateView(UpdateView): model = User form_class = ClientsUserForm second_form_class = ClientsForm template_name = ''admin/client_update.html'' def get_context_data(self, **kwargs): context = super(ClientUpdateView, self).get_context_data(**kwargs) context[''active_client''] = True if ''form'' not in context: context[''form''] = self.form_class(self.request.GET) if ''form2'' not in context: context[''form2''] = self.second_form_class(self.request.GET) context[''active_client''] = True return context def get(self, request, *args, **kwargs): super(ClientUpdateView, self).get(request, *args, **kwargs) form = self.form_class form2 = self.second_form_class return self.render_to_response(self.get_context_data( object=self.object, form=form, form2=form2)) def post(self, request, *args, **kwargs): self.object = self.get_object() form = self.form_class(request.POST) form2 = self.second_form_class(request.POST) if form.is_valid() and form2.is_valid(): userdata = form.save(commit=False) # used to set the password, but no longer necesarry userdata.save() employeedata = form2.save(commit=False) employeedata.user = userdata employeedata.save() messages.success(self.request, ''Settings saved successfully'') return HttpResponseRedirect(self.get_success_url()) else: return self.render_to_response( self.get_context_data(form=form, form2=form2)) def get_success_url(self): return reverse(''client_list'')


Debería poder usar el kwarg "instancia" para la instanciación del formulario de un modelo existente si eso es lo que necesita. Ejemplo:

context[''form''] = self.form_class(self.request.GET, instance=request.user)


Intenta salir del self.request.get en los constructores de formularios get_content_data y utiliza la variable "object". Con eso get reiniciar el constructor, más en este enlace .

Mi código:

context[''form''] = self.form_class(instance=self.object)