Monday, September 7, 2015

Re: Multiple model form (not in line) on same page

class MultiModeloForm():
'''
Permite construir un formulario con los campos que se le especifiquen dado un `modelo`.
La relación del campo con el modelo puede ser tan larga como se desee, mientras se siga el formato
campo__campo.

Cuando los atributos son relaciones se puede especificar la relación o tomar atributos de la relación así:
* modelo__modelo_relacionado

Si se quieren atributos de la clase relacionada se puede solicitar nombrandolos:
* modelo__modelo_relacionado__atributo

.. note::
Cuidado con el guardado de este formulario, ya que no se puede garantizar que todos los campos requeridos
para construir los modelos están dentro del formulario, es decir, **NO** haga esto:

.. code:: python

form = MultiModeloForm(Modelo, [campo1, campo2])
formi = form.get_formulario()
formi.save()

'''
modelo = None
campos_modelos=None
campo_buscado=None
formulario=None
#FIXME inventarse una cache
def get_model_form(self, Model, Fields):
class ModelForm(forms.ModelForm):
class Meta:
model = Model
fields = Fields
return ModelForm

def buscar_campo(self, clase, campo):
if not '__' in campo:
fields = []
fields += clase._meta.fields
if hasattr(clase._meta, 'many_to_many') :
fields += clase._meta.many_to_many

for field in fields:
if campo == field.name:
if not clase.__name__ in self.campos_modelos:
self.campos_modelos[clase.__name__] = [clase]
self.campos_modelos[clase.__name__].append((field.name, self.campo_buscado))
return field
raise AttributeError
else:
campo_sp = campo.split('__')
campos = get_campos_por_clase(clase)
if campo_sp[0] in campos:
claser = campos[campo_sp[0]].related.parent_model
return self.buscar_campo( claser, '__'.join(campo_sp[1:]))
else:
raise AttributeError

def __init__(self, clase_base, campos):
'''
Esta clase es una constructora de formularios, no es el formulario.
para obtener el formulario debe hacer form.get_formulario()

'''
base = clase_base.__name__
self.campos_modelos = {}
self.modelo=clase_base
for x in campos:
self.campo_buscado = x
self.buscar_campo(clase_base, x)

formularios = {}
base_modelo = None
base_campos = None
for nombre, valores in self.campos_modelos.items():
modelo = valores[0]
fields = []
nombres_campos = SortedDict(valores[1:])
for x,y in nombres_campos.items():
fields.append(x)

if nombre == base:
base_modelo = modelo
base_campos = fields
else:
form = self.get_model_form(modelo, fields)()
# FIXME revisar para que sirve formularios[nombre]
#formularios[nombre] =[]
for nombre_f, valor in zip(form.fields.keys(), form.fields.values()):
if nombre_f in nombres_campos:
formularios[nombres_campos[nombre_f]] = valor

if not base_modelo:
base_modelo = clase_base
base_campos = []

class Multi_Model_Form(forms.ModelForm):
for nombre, valor in formularios.items() + [(None, None)]:
if nombre:
exec "%s = valor" % (nombre)
else:
exec "pass"

class Meta:
model=base_modelo
fields = base_campos


self.formulario = Multi_Model_Form

def get_formulario(self):
'''
Retorma el formulario creado
'''
return self.formulario

def get_modelo(self):
'''
Permite saber el modelo base del formulario
'''
return self.modelo

Hi,

Sorry  some time ago I saw this project https://github.com/sikaondrej/django-multi-model-form, but now is not found, 

I did a copy of the code, but it is in spanish, I don't have time to translate this now but can be useful.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CAG%2B5VyOoHVuOH8EQa5HdfWfgqed%2BoaBoBHmnTov45VVZACi%3D2Q%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment