Reverse Queryset on Django models


I'm trying to access a model in reverse. To access the Vale model by consulting the model DetailVale is as follows:

val= DetalleVale.objects.filter(vale__usuarioVale=usuario).filter(vale__statusFinalizado=1)

However I need to consult about the Vale model and through this arrive at the properties of DetalleVale and be able to use the fields cardboard, name, part, etc.

My models:

class Vale(models.Model):
 fechaCreacion = models.DateTimeField(auto_now_add=True)
 linea   = models.IntegerField(choices=LINEAS.CHOICES_LINEAS, default=LINEAS.SELECCIONAR)
 lote          = models.TextField(max_length=50)
 turno   = models.IntegerField(choices=TURNOS.CHOICES_TURNOS, default=TURNOS.SELECCIONAR)
 usuarioVale   = models.ForeignKey(User)
 statusFinalizado = models.IntegerField(default=0)
 statusAutorizacion=models.IntegerField(choices=ESTADOS.CHOICES_ESTADOS, default=ESTADOS.SELECCIONAR)
 vigenciaVale = models.IntegerField(choices=STATUSVALE.CHOICES_STATUSVALE, default=STATUSVALE.ACTIVO)

class Meta:
    verbose_name = 'Vales'
    verbose_name_plural = 'Vale'

def __str__(self):
    return '%s' % (

class DetalleVale(models.Model):
 fechaCreacion       = models.DateTimeField(auto_now_add=True)
 vale                = models.ForeignKey(Vale)
 cartonNo = models.CharField(max_length=50)
 nombreM = models.CharField(max_length=50, null=True)
 parte       = models.CharField(max_length=50, null=True)
 descripcion = models.CharField(max_length=50, null=True)
 multiplo   = models.IntegerField()
 cantidad            = models.IntegerField(default=1)
asked by Noel L 06.02.2018 в 22:14

2 answers


It is possible to do it, you simply have to follow the inverse relationship that you have defined. You can usually name that relationship with the name you want using related_name :

class DetalleVale(models.Model):
 # ...
 vale                = models.ForeignKey(Vale, related_name='detalles')
 # ...

When you do not explicitly define the name then the default relationship is a mixture of the model name with the word _set . Since your model is called DetalleVale then the inverse relationship created by Django would be detallevale_set .

Having this clear, your query can do it in the following way:

vales = Vale.objects.filter(
for vale in vales:
    # hacer algo por aquí

In this way you get all the "Vouchers" whose details are xxx for cartonNo , yyy for nombreM , etc.

Be careful, you do not need to nest the calls to the filter method to simulate the condition AND in the database since AND is the condition used by default.

You will also wonder what Django's ORM does internally when doing that type of queries. The answer is quite simple: it makes a JOIN .

answered by 10.02.2018 / 15:55

What you mention can not be done since being Vale fk of details It is valid if you access from ticket to detailsVale will give you a list, what you can do is the following:

vales = Vale.objects.filter(.....) # añades los filtros que necesites
# con el siguiente for recorreras los detalles que pertenecen al modelo vale en cuestion
 for vale in vales:
     detalles = DetalleVale.objects.filter(vale=vale)
     for d in detalles:
        print d.nombreM
        print d.cartonNo
answered by 07.02.2018 в 17:29