Lev
Lev

Reputation: 1009

Reverse lookup 'QuerySet' object has no attribute

I have the following Models where I define a trucking company and their insurance company. Models.py:

class Truckers(models.Model):
    DOT_Number = models.IntegerField(primary_key=True)
    Address = models.CharField( max_length=200)  

class CaliIns_FK(models.Model):
    DOTNmb = models.ForeignKey(Truckers, on_delete=models.CASCADE) 
    CoName = models.CharField(max_length=20)

There are many truckers and not as many insurance companies. I am trying to get a list of every Trucker that has insurance.

I tried the following as per django:

truck = Truckers.objects.all()
filtered = truck.caliinsfk_set.filter(truckers__isnull=True)

and

filtered = truck.caliins_fk_set.filter(truckers__isnull=True)

getting error:

AttributeError: 'QuerySet' object has no attribute 'caliinsfk_set'

Upvotes: 1

Views: 904

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476594

Given you want Truckers objects with no related CaliIns_FK, you can .filter() your Trucks:

Truckers.objects.filter(caliins_fk__isnull=True)

or given the ForeignKey has a related_name, it should be:

Truckers.objects.filter(myrelatedname__isnull=True)

(with myrelatedname the value in related_name for the ForeignKey) Here we thus obtain a QuerySet for which there is no related CaliIns_FK object.

This results in a query with a LEFT OUTER JOIN so if the "set" of related CaliIns_FKs is empty, it will have a row with NULL:

SELECT truckers.*
FROM truckers
LEFT OUTER JOIN caliins_fk ON truckers.DOT_Number = caliins_fk.DOTNmb_id
WHERE caliins_fk.id IS NULL

Note that one typically does not uses plural names for models, or the name of a primary key in a foreign key. According to PEP-8, attributes also are written in lowercase and with underscores. A more Django-ish approach would be:

class Trucker(models.Model):
    dot_number = models.IntegerField(primary_key=True)
    address = models.CharField( max_length=200)

CaliInsurance(models.Model):
    trucker = models.ForeignKey(Trucker, on_delete=models.CASCADE)
    coname = models.CharField(max_length=20)

In that case the query thus looks like:

Trucker.objects.filter(caliinsurance__isnull=True)

Upvotes: 1

Related Questions