2010-04-15 20 views
192

¿Cuál es el argumento related_name útil para los campos ManyToManyField y ForeignKey? Por ejemplo, dado el siguiente código, ¿cuál es el efecto de related_name='maps'?¿Para qué se utiliza `related_name` en Django?

class Map(db.Model): 
    members = models.ManyToManyField(User, related_name='maps', 
            verbose_name=_('members')) 
+9

@DanielRoseman ¿Es de alguna manera bueno para el rendimiento o las buenas prácticas usar related_name = '+' cuando la relación hacia atrás no es necesaria? – lajarre

+7

Me gustaría saber la respuesta a la pregunta de @ lajarre. – 3cheesewheel

+1

@lajarre - Supongo que no cambiará el rendimiento en absoluto. Tuve que usarlo una vez con los tipos de contenido de FeinCMS. Personalmente, creo que es una buena práctica especificar siempre el 'related_name' así que si sabes que no lo usarás, supongo que es algo bueno. Esa es una opinión personal, por supuesto. –

Respuesta

275

El atributo related_name especifica el nombre de la relación inversa entre el modelo User de nuevo a su modelo.

Si no especifica un related_name, Django crea automáticamente una utilizando el nombre de su modelo con el sufijo _set, por ejemplo User.map_set.all().

Si hace especifique, p. Ej. related_name=maps en el modelo User, User.map_set seguirá funcionando, pero la sintaxis User.maps. es, obviamente, un poco más limpia y menos torpe; por ejemplo, si tiene un objeto de usuario current_user, puede usar current_user.maps.all() para obtener todas las instancias de su modelo Map que tengan relación con current_user.

El Django documentation tiene más detalles.

+1

De acuerdo, sé que esta es una publicación anterior. Pero estoy tratando de resolver esto: ¿cuál es el truco + al final del nombre relacionado? Por ejemplo, ¿qué sucede si hice 'related_name = 'maps +'' en el ejemplo anterior? – Sidd

+4

si agrega +, django deshabilita la asignación – josephmisiti

+2

para OneToOneField nombre_relacionado predeterminado será nombre de clase de caso pequeño. Por ejemplo, en el ejemplo dado si los miembros serían OneToOnefield, entonces funcionará "User.map". – ancho

32

Para agregar al nombre relacionado con la respuesta existente es imprescindible en caso de que haya 2 FK en el modelo que apuntan a la misma tabla. Por ejemplo en el caso de Bill de material

@with_author 
class BOM(models.Model): 
    name = models.CharField(max_length=200,null=True, blank=True) 
    description = models.TextField(null=True, blank=True) 
    tomaterial = models.ForeignKey(Material, related_name = 'tomaterial') 
    frommaterial = models.ForeignKey(Material, related_name = 'frommaterial') 
    creation_time = models.DateTimeField(auto_now_add=True, blank=True) 
    quantity = models.DecimalField(max_digits=19, decimal_places=10) 

Así que cuando usted tendrá que acceder a estos datos sólo se puede utilizar el nombre relacionado

bom = material.tomaterial.all().order_by('-creation_time') 

No está funcionando de otra manera (al menos yo no era capaz omitir el uso del nombre relacionado en caso de 2 FK en la misma tabla.)

+1

Tienes que elegir un nombre relacionado al menos para uno de ellos. El otro no necesariamente requiere. –

+3

'related_name' debe ser plural. Porque las relaciones ForeignKey devuelven varios objetos. –

Cuestiones relacionadas