¿Para qué se utiliza `related_name` en Django?

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

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

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

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

Si especifica, por ejemplo, related_name=maps en el modelo de User , User.map_set seguirá funcionando, pero User.maps. la syntax es obviamente un poco más limpia y menos torpe; así, por ejemplo, si tuviera un objeto de usuario current_user , podría usar current_user.maps.all() para obtener todas las instancias de su modelo de Map que tengan una relación con current_user .

La documentación de Django tiene más detalles.

Para agregar a la respuesta existente, el nombre relacionado es una necesidad en caso de que haya 2 FK en el modelo que apunten a la misma tabla. Por ejemplo en caso de factura 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) 

Entonces, cuando tenga que acceder a estos datos, solo puede usar el nombre relacionado

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

No funciona de otra manera (al menos no pude omitir el uso del nombre relacionado en el caso de 2 FK en la misma tabla).

El argumento related_name también es útil si tiene nombres de clase relacionados más complejos. Por ejemplo, si tiene una relación de clave externa:

 class UserMapDataFrame(models.Model): user = models.ForeignKey(User) 

Para acceder a los objetos UserMapDataFrame del User relacionado, la llamada predeterminada sería User.usermapdataframe_set.all() , que es bastante difícil de leer.

El uso de related_name permite especificar un nombre más simple o más legible para obtener la relación inversa. En este caso, si especifica user = models.ForeignKey(User, related_name='map_data') , la llamada sería User.map_data.all() .

El parámetro de nombre relacionado es en realidad una opción. Si no lo configuramos, Django crea automáticamente el otro lado de la relación para nosotros. En el caso del modelo Map, Django habría creado un atributo map_set , permitiendo el acceso a través de m.map_set en su ejemplo (m es su instancia de clase). La fórmula que usa Django es el nombre del modelo seguido de la cadena _set . Por lo tanto, el parámetro de nombre relacionado simplemente reemplaza el valor predeterminado de Django en lugar de proporcionar un nuevo comportamiento.