5

¿Cómo se puede verificar el tipo de campo de muchos a muchos en django?¿Cómo verificar el tipo de campo de muchos a muchos en django?

que quería hacer de esta manera:

import django 
field.__class__ == django.db.models.fields.related.ManyRelatedManager 

esto no funciona, porque la clase ManyRelatedManager no se puede encontrar. Pero si lo hago field.__class__ la salida es django.db.models.fields.related.ManyRelatedManager

¿Por qué se refiere a una clase que no parece existir y cómo puedo llevarla a cabo?

Muchas gracias por su ayuda.

Respuesta

5

Si ya tiene la instancia de campo puede simplemente hacer:

if isinstance(field, ManyToManyField): 
    pass // stuff 

Si sólo tiene la instancia del gestor relacionada, puede búsqueda inversa el instancia de campo:

>>> print fm 
<class 'django.db.models.fields.related.ManyRelatedManager'> 
>>> print fm.instance._meta.get_field_by_name('fieldnamehere') 
(<django.db.models.fields.related.ForeignKey: fieldnamehere>, None, True, False) 

Esto sólo se ha probado en Django 1.5

+0

Esta sería la manera perfecta, pero no sé cómo obtener la instancia de campo de un campo de muchos a muchos, que se encuentra en el modelo de destino ... si pudiera ayudarme con esto, accecpt su respuesta :) – amann

+1

Puedo listar todos los campos con 'object._meta.get_all_field_names()' pero no se puede acceder al nombre de campo correspondiente a través de 'object._meta.get_field ('fieldname')'. Puedo usar la función 'object._meta.get_field_by_name ('fieldname')' que saca '(, None, False, True)'. En realidad, no sé cómo sacar la instancia de campo de eso ... – amann

+1

lo tengo :) ... es: 'object._meta.get_field_by_name (" fieldname ") [0] .field' – amann

12

Debería poder verificarlo como una cadena.

field.__class__.__name__ == 'ManyRelatedManager' 
+1

¡Gracias por la respuesta rápida! ¿Pero no es eso un poco dinámico? En realidad, no creo que se cambie el nombre de la clase "ManyRelatedManager", pero ¿no es un poco descuidado? Pero, sin embargo, creo que usaré esta respuesta, porque es más eficiente que la de lazerscience. ¡Gracias! – amann

0

No estoy muy seguro de lo que está tratando de lograr, pero supongo que lo mejor será buscar en el atributo de su modelo _meta para determinar la clase de campo! echa un vistazo a _meta.fields y _meta.many_to_many!

Se podría hacer algo como:

field_class = [f for f in yourmodel._meta.many_to_many if f.name=='yourfield'][0].__class__ 
0

(usando Django 1.11)

Esta pregunta se ha vuelto confusa, porque el comportamiento informado no es el comportamiento moderno de un campo relacionado. Ejemplo aquí, donde JobTemplate es la clase del modelo, y credentials es una relación muchos-a-muchos campos relacionados:

>>> JobTemplate._meta.get_field('credentials').__class__ 
django.db.models.fields.related.ManyToManyField 

¿Es diferente si inspeccionamos la _meta de un objeto?

>>> JobTemplate.objects.first()._meta.get_field('credentials').__class__ 
django.db.models.fields.related.ManyToManyField 

no.

Así que aquí es cuando inserto lo que creo que es el escenario más probable de alguien que viene aquí. Usted tiene esto:

>>> JobTemplate.objects.first().credentials 
<django.db.models.fields.related_descriptors.ManyRelatedManager at 0x6f9b390> 

Nota, esto es lo que tenía el OP.

Voy a estipular que el modelo relacionado es Credential. ¡Puedo verificar si este es un administrador de credenciales relacionado!

>>> isinstance(JobTemplate.objects.first().credentials, Credential.objects.__class__) 
True 

campos ManyToMany pueden ser muy difíciles de procesar, porque el atributo mata a sí mismo y se reemplaza con la subclase gerente. También puede hacer una referencia cruzada de esta información con el campo obtenido de get_field('credentials') para estar más seguro.La verificación anterior isinstance también podría recoger erróneamente a otros administradores que haya establecido en el modelo. Sin embargo, esta sigue siendo una valiosa prueba para ver si el atributo que tiene "corta" la forma en que debe funcionar un campo ManyToMany de ese modelo particular relacionado.

Cuestiones relacionadas