Question

I want to know how to write a join condition in django query for the following SQL query:

SELECT
    s.name,
    l.name,
    a.name,
    a.asset_code,
    c.name,
    ad.name,
    a.model_no,
    a.serial_no
FROM
    asset_mgmt_asset_assignment_employee ae,
    asset_mgmt_asset a,
    asset_mgmt_department ad,
    asset_mgmt_employee e,
    asset_mgmt_sublocation s,
    asset_mgmt_location l,
    asset_mgmt_asset_category c
WHERE
    ae.asset_id = a.id AND
    ae.department_id = ad.id AND
    ae.employee_id = e.id AND
    ad.location_id = l.id AND
    l.Sublocation_id = s.id AND
    c.id = a.asset_category_id AND
    s.id = 2;

How can we mix all these tables in a django query?

Was it helpful?

Solution

This query does not translate straightforwardly into Django. Django queries produce objects, not tuples. You need to think in terms of objects and their relationships instead of tuples and relations.

Of course, that's assuming an ORM is appropriate for your use case in the first place. If you find yourself writing lots of queries like this, it might not be. ORMs are best if you want to keep all of your business logic in high-level application code and treat the database as a persistence layer for objects. They aren't so good at expressing arbitrary queries such as this one. Personally, I don't really like ORMs. I would prefer to keep most relational logic in views, and occasionally query those views from application code (with very simple queries). But this is getting into subjective opinion. ORMs do have value and can be useful if you want to follow an MVC-like framework, while a more relational solution will generally produce less layered code.

OTHER TIPS

You don't write join queries in django directory. Django has an engine that determines when joins should be created and it will take care of that for you.

Your challenge is to create your models correctly for the relationships between them; and then let the ORM worry about creating the queries and the tables.

From your query above, here is one possible way to map it to the ORM and then write the equivalent api call to fetch all related objects to an asset. Of course not everything is covered here but it should give you an idea:

class Department(models.Model):
    name = models.CharField(max_length=100)

    def __unicode__(self):
        return unicode(self.name)

class Location(models.Model):
    name = models.CharField(max_length=100)
    parent = models.ForeignKey('self', blank=True, null=True)

    def __unicode__(self):
        return unicode(self.name)

class AssetCategory(models.Model):
    name = models.CharField(max_length=100)

    def __unicode__(self):
        return unicode(self.name)

class Employee(models.Model):
    name = models.CharField(max_length=100)
    department = models.ForeignKey(Department)

    def __unicode__(self):
        return unicode(self.name)

class Asset(models.Model):
    name = models.CharField(max_length=100)
    model_number = models.CharField(max_length=100)
    serial_number = models.CharField(max_length=100)
    employee = models.ForeignKey(Employee)
    location = models.ForeignKey(Location)
    category = models.ForeignKey(AssetCategory)

Then your query is:

assets = Asset.objects.filter(location=Location.objects.get(id=2))
for asset in assets:
    print('{0.id}, {0.name}, {0.model_number}, {0.serial_number}'.format(asset))
    print('{0.employee}, {0.employee.department}, {0.location}'.format(asset)) 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top