SQL query to DJset's queryset


I have the following SQL query:

SELECT DISTINCT ON (e.id) e.id, e.nombre, e.apellido, e.estado, e.documento, c.nivelado, s.nombre AS semestre, t.nombre AS tipo 
            FROM estudiante e 
                JOIN caracterizacion c ON c.estudiante_id = e.id 
                JOIN semestre s ON s.id=c.semestre_id 
                JOIN tipo t ON t.id=c.tipo_id 
                ORDER BY e.id, s.orden DESC

I want to do it with Queryset from djanango something like that estudiantes = Estudiante.objects.all() but I do not know how to do the join and the order by.

This is my database model:

I leave the models involved in the query


    (0, 'Activo'),
    (1, 'Inactivo'),
    (2, 'Egresado'),
    (3, 'Graduado'),
    (0, 'Tarjeta de indentidad'),
    (1, 'Cédula'),
    (2, 'Pasaporte'),
    (3, 'Cédula extrangera'),

class Genero(models.Model):
    nombre = models.CharField(verbose_name="Nombre", max_length=200)

    def __str__(self):
        return self.nombre

    class Meta:
        db_table = 'genero'

class Estudiante(models.Model):

    nombre = models.CharField(verbose_name="Nombres", max_length=200)
    apellido = models.CharField(verbose_name="Apellidos", max_length=200)
    tipo_documento = models.IntegerField(choices=TIPOS_DOCUMENTOS, default=1)
    documento = models.CharField(verbose_name="Número de documento", max_length=200, unique=True)
    celular = models.CharField(verbose_name="Celular", max_length=200, null=True, blank=True)
    telefono = models.CharField(verbose_name="Telefono", max_length=200, null=True, blank=True)
    genero = models.ForeignKey(Genero, verbose_name="Género", on_delete=models.CASCADE)
    fecha_nacimiento = models.DateField(verbose_name="Fecha de nacimiento")
    email = models.EmailField(verbose_name="Correo electronico", null=True, blank=True, unique=True)
    direccion = models.CharField(verbose_name="Dirección", max_length=200, null=True, blank=True)
    foto = models.ImageField(upload_to=custom_upload_to, null=True, blank=True)
    programa = models.ForeignKey(Programa, on_delete=models.CASCADE)
    estado = models.IntegerField(choices=ESTADOS, default=0)
    semestre_inicio = models.ForeignKey(Semestre, on_delete=models.CASCADE)
    created = models.DateTimeField(auto_now_add=True, verbose_name="Fecha de creación")

    def __str__(self):
        return ('{} {}'.format(self.nombre, self.apellido))

    def get_tipo_documento(self):
        tipo = TIPOS_DOCUMENTOS[self.tipo_documento][1]
        return tipo

    class Meta:
        db_table = 'estudiante'


class Semestre(models.Model):
    nombre = models.CharField(verbose_name="Nombre", max_length=200, unique=True)
    orden =  models.IntegerField(null=False, blank=False, unique=True)

    def __str__(self):
        return self.nombre

    class Meta:
        ordering = ['orden']
        db_table = 'semestre'


class Tipo(models.Model):
    nombre = models.CharField(verbose_name="Nombre", max_length = 200)
    default = models.NullBooleanField(null=True, blank=True, unique=True)
    def __str__(self):
        return self.nombre

    class Meta:
        verbose_name = "Tipo de caracterización"
        verbose_name_plural = "Tipo de caracterizaciones"
        ordering = ['nombre']
        db_table = 'tipo'

class Caracterizacion(models.Model):
    SI_NO = (
    estudiante = models.ForeignKey(Estudiante, verbose_name="Estudiante", on_delete=models.CASCADE)
    descripcion = models.TextField(verbose_name="Descripción", null=True, blank=True)
    semestre = models.ForeignKey(Semestre, verbose_name="Semestre", on_delete=models.CASCADE)
    tipo = models.ForeignKey(Tipo, verbose_name="Tipo", on_delete=models.CASCADE)
    nivelado = models.IntegerField(choices = SI_NO, default=1)
    usuario = models.ForeignKey(User, verbose_name="Usuario", on_delete=models.CASCADE)
    created = models.DateTimeField(auto_now_add=True, verbose_name="Fecha de creación")

    def __str__(self):
        return ('{} - {}'.format(self.estudiante, self.semestre))

    class Meta:
        verbose_name = "Caracterización"
        verbose_name_plural = "Caracterizaciones"
        ordering = ['created']
        db_table = 'caracterizacion'
asked by Cesar Martinez Quiroga 21.11.2018 в 07:04

1 answer


the joins are simply made equal

caracterizaciones = Caracterizacion.objects.filter(....) # los puntos suspensivos los para indicar que apliques los filtros que necesites
semestres = Semestre.objects.filter(...)
tipo = Tipo.objects.get(id=param_id) # param_id es una variable que me invento  e imagino que tiene un valor que recibo como parametro
# sabiendo que '.filter()' devuelve una lista y '.get()' un objeto
estudiantes = Estudiante.objectst.filter(
    caracterizacion__in=caracterizaciones, # a este atributo le añado '__in' porque estoy igualando con una lista
    tipo=tipo # aqui solo igualo porque 'tipo' es un único objecto

I've done you with filter and get to make the example with the two cases but you can do it as you need.

It should be noted that I can apply the caracterizacion filter from the Estudiante model even if it does not have this attribute because the model Caracterizacion has an FK attribute of Estudiante Django with its magic creates an internal link to make us the easier life.

To learn more about how to work with Django, check out this link.

answered by 23.11.2018 в 23:14