Foros del Web » Programando para Internet » Python »

claves foraneas en formularios Django

Estas en el tema de claves foraneas en formularios Django en el foro de Python en Foros del Web. Buenas, otra duda que tengo. A ver si pueden ayudarme por favor. Tengo un formulario que extiende de la clase ModelForm de django. El detalle ...
  #1 (permalink)  
Antiguo 22/07/2011, 07:04
 
Fecha de Ingreso: marzo-2011
Ubicación: Caracas
Mensajes: 389
Antigüedad: 13 años, 1 mes
Puntos: 16
claves foraneas en formularios Django

Buenas, otra duda que tengo. A ver si pueden ayudarme por favor. Tengo un formulario que extiende de la clase ModelForm de django. El detalle esta en que el formulario extiende de un model llamado "trabajos" se ingresan los detalles de los trabajos por el usuario. Este model tiene un campo usuario_id que hace el foreign key con el usuario. Pero al traerme el formulario completo me trae el combo de seleccion de usuario. y si la clase Meta del formulario le pongo que me excluya ese campo. no me permite guardarlo. Hay una forma de que yo pueda filtrar ese combo a que me traiga unicamente el usuario activo? o el dato que necesito?.
  #2 (permalink)  
Antiguo 22/07/2011, 08:43
 
Fecha de Ingreso: agosto-2008
Mensajes: 198
Antigüedad: 15 años, 8 meses
Puntos: 27
Respuesta: claves foraneas en formularios Django

Para filtrar el campo podrías pasar al formulario el usuario como parámetro y en una función como el init restringir el queryset:
Código:
self.fields['usuario'].queryset = Usuario.objects.filter(id=parametro.id)
Ahora con esto se te verá en la plantilla sí o sí como un select, quizás sería más agradable no mostrarlo, redifiniendo el widget como hidden y usando como initial el id del usuario.

También podrías hacer esto, si el campo usuario puede ser nulo o blanco pasar como parámetro al usuario, dejar guardado como atributo del formulario a éste y en el método clean hacer algo como:
Código:
self.cleaned_data['usuario'] = usuario
Así daría lo mismo si muestras o no en el template el campo.

Otra cosa que podrías hacer es excluir el campo y después del save agregar el usuario:
Código:
registro = form.save()
registro.usuario = usuario
registro.save()
Aunque en este caso probablemente sería adecuado englobar la funcion en una transacción para asegurarte de no guardar, jamás, el formulario sin guardar también el usuario.

No se sí habrán formas más trasparentes de lograrlo, pero esas son las que se me ocurren. Saludos.
  #3 (permalink)  
Antiguo 22/07/2011, 09:19
 
Fecha de Ingreso: marzo-2011
Ubicación: Caracas
Mensajes: 389
Antigüedad: 13 años, 1 mes
Puntos: 16
Respuesta: claves foraneas en formularios Django

Muchas gracias. pero tengo dos dudas con respecto a lo que me dijiste.
Intente hacer el ultimo ejemplo.
Cita:
Código:
registro = form.save()
registro.usuario = usuario
registro.save()
y me dice que la columna usuario_id no puede estar vacia como si no tomara la asignacion "registro.usuario = usuario" y lo otro es en el caso de usar
Código Python:
Ver original
  1. self.fields['usuario'].queryset = Usuario.objects.filter(id=parametro.id)
como le paso ese parametro.id al metodo __init__??? y perdona pero es q aun no comprendo mucho el funcionamiento del metodo.
  #4 (permalink)  
Antiguo 22/07/2011, 09:34
 
Fecha de Ingreso: marzo-2011
Ubicación: Caracas
Mensajes: 389
Antigüedad: 13 años, 1 mes
Puntos: 16
Respuesta: claves foraneas en formularios Django

ok. hice esto como comentaste muestro el codigo:
views.py
Código Python:
Ver original
  1. ced = usuario.objects.get(cedula=cedu)
  2. id=ced.id
  3.   form = trabajos(id)
y este el codigo __init__ del formularios.py
Código Python:
Ver original
  1. class trabajos(forms.ModelForm):
  2.  
  3.   class Meta:
  4.     model = Trabajos
  5.     exclude=('usuario')
  6.   def __init__(self,id, *args, **kwargs):
  7.     super(Trabajos, self).__init__(*args, **kwargs)
  8.     #self.fields['usuario'].widget.attrs['hidden'] = 'hidden'
  9.     self.fields['usuario'].queryset = Usuario.objects.get(id=id)
Segun probando lo que entendi. y me toma el parametro id que le paso. pero me muestra el siguiente error:

Cita:
Django Version: 1.2.3
Exception Type: KeyError
Exception Value:
'trabajador'
Exception Location: /home/proyecto/formularios.py in __init__, line 41
la linea 41 es "self.fields['usuario'].queryset = Usuario.objects.get(id=id)"
  #5 (permalink)  
Antiguo 22/07/2011, 09:35
 
Fecha de Ingreso: marzo-2011
Ubicación: Caracas
Mensajes: 389
Antigüedad: 13 años, 1 mes
Puntos: 16
Respuesta: claves foraneas en formularios Django

lo probe con filter en vez de get. y es iwal.
  #6 (permalink)  
Antiguo 22/07/2011, 09:39
 
Fecha de Ingreso: marzo-2011
Ubicación: Caracas
Mensajes: 389
Antigüedad: 13 años, 1 mes
Puntos: 16
Respuesta: claves foraneas en formularios Django

jajajjajajaja. el error era porq no le habia quitado el exclude en la class Meta!!!!!!1 jajajajajajaj. muchas gracias
refreegrata!!!!! por la pronta respuesta. y la clase. jajajaja. :D

Solo me queda una duda. como hago para ponerle el parametro como initial? para que me lo tome por defecto???????

Última edición por rjulio21; 22/07/2011 a las 09:51
  #7 (permalink)  
Antiguo 22/07/2011, 09:56
 
Fecha de Ingreso: agosto-2008
Mensajes: 198
Antigüedad: 15 años, 8 meses
Puntos: 27
Respuesta: claves foraneas en formularios Django

Espera un poco, no tienes que usar todos, yo te mostré 3 formas de hacerlo, pero tú deberías, si decides usar alguna de las alternativas, usar sólo una:

Opción 1:
----------
Cita:
Iniciado por refreegrata Ver Mensaje
Para filtrar el campo podrías pasar al formulario el usuario como parámetro y en una función como el init restringir el queryset:
Código:
self.fields['usuario'].queryset = Usuario.objects.filter(id=parametro.id)
Ahora con esto se te verá en la plantilla sí o sí como un select, quizás sería más agradable no mostrarlo, redifiniendo el widget como hidden y usando como initial el id del usuario.
Opción 2:
----------
Cita:
Iniciado por refreegrata Ver Mensaje
También podrías hacer esto, si el campo usuario puede ser nulo o blanco pasar como parámetro al usuario, dejar guardado como atributo del formulario a éste y en el método clean hacer algo como:
Código:
self.cleaned_data['usuario'] = usuario
Así daría lo mismo si muestras o no en el template el campo.
Opción 3
----------
Cita:
Iniciado por refreegrata Ver Mensaje
Otra cosa que podrías hacer es excluir el campo y después del save agregar el usuario:
Código:
registro = form.save()
registro.usuario = usuario
registro.save()
Aunque en este caso probablemente sería adecuado englobar la funcion en una transacción para asegurarte de no guardar, jamás, el formulario sin guardar también el usuario.
La última sólo funcionará si el campo no es obligatorio, ya que si no te va a dar un error al intentar el form.save(). Si mal no recuerdo, en ese caso podrías hacer algo como:
Código:
registro = form.save(commit=False)
registro.usuario = usuario
registro.save()
Así no se guardaría el registro hasta llegar hasta la línea registro.save().

Ahora para agregar un valor inicial en una función como el init puedes hacer algo como
Código:
self.fields['campo'].initial = valor
Saludos.

Última edición por refreegrata; 22/07/2011 a las 10:21
  #8 (permalink)  
Antiguo 22/07/2011, 11:04
 
Fecha de Ingreso: marzo-2011
Ubicación: Caracas
Mensajes: 389
Antigüedad: 13 años, 1 mes
Puntos: 16
Respuesta: claves foraneas en formularios Django

ok. Muchas gracias. pero no entendiste lo que quise decir. me referia a que inicialmente use la tercera opcion que diste y me dio error, exactamente por eso, porq el campo es obligatorio. luego use la primera. y si me funciono perfect. pero no sabia como darle el valor inicial. pero ya todo lo hice y me corrio perfecto. Muchas gracias igual por tu explicacion, me aclaraste bien varias dudas. :D
  #9 (permalink)  
Antiguo 22/07/2011, 11:06
 
Fecha de Ingreso: marzo-2011
Ubicación: Caracas
Mensajes: 389
Antigüedad: 13 años, 1 mes
Puntos: 16
Respuesta: claves foraneas en formularios Django

No habia visto la actualizacion de tu comentario. Muchas gracias. perfecto. :D Al final lo hice modificando el metodo __init__ como explicaste en la primera. :D

Etiquetas: claves, django, formulario, foreignkey
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 17:14.