Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

226
Vistas
Django recursive query on non-symmetrical Many-to-Many to the same model

I'm offering services to companies (many-to-many between Service and Company). To structure my services, I use a tree-like structure using Django's many-to-many field. So, a service can contain multiple other services.

The question: how can I retrieve all services a company has? Using company.services, I only get the services directly related to that company. I need the directly related ones + included_services (in a recursive way).

class Company(models.Model):
    services = models.ManyToManyField(Service)

class Service(models.Model):
    name = models.CharField(max_length=255)
    included_services = models.ManyToManyField("self", blank=True, symmetrical=False)
over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

I don't think you can do this using Django's ORM framework or writing a plain raw SQL statement. You might want to take a look at 3rd party libraries like django-mptt that enables you to store/retrieve models represented in tree-like structures more efficiently.

However, if you want to do it via Python, here is what you can do:

def get_services(company):
    services = list(company.services.all())
    result = []
    while services:
        service = services.pop(0)
        result.append(service)
        services.extend(list(service.included_services.all()))
    return result

The above idea is very similar to performing a breadth-first search in a tree.

over 4 years ago · Santiago Trujillo Denunciar

0

I forgot to mention that I needed a QuerySet as return value, so I modified @ozgur's exellent answer a bit. Just in case someone also needs this:

def get_services(company):
    services = list(company.services.all())
    pks = []
    while services:
        service = services.pop(0)
        if service.pk not in pks:
            pks.append(service.pk)
            services.extend(list(service.included_services.all()))
    return Service.objects.filter(pk__in=pks)

EDIT: I also added a check for potential loops.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda