Naser Hamidi
Naser Hamidi

Reputation: 176

django make complex queryset

I am writing an app where I have a house with many family in it and just one of Fathers or Mothers is head of house:

class House(models.Model):
    ....
    def get_head_of_house(self)
    #searchs in fathers and mothers and find which one is head of house
    #and returns it
class Fathers(models.Model):
    house = models.ForiegnKey(House)
    first_name = models.CharField()
    last_name = models.CharField()
    is_head = models.BooleanField()
    ....
class Mothers(models.Model):
    house = models.ForiegnKey(House)
    first_name = models.CharField()
    last_name = models.CharField()
    is_head = models.BooleanField()
    ....

In search form, I get first name and last name of head of a house. I want to search in fathers and mothers and select head of all houses where form.fname is in their first_name or form.lname is in their last_name

The problem is where heads are in separate models and I care about matching either first-name or last-name and more important queryset can not be filled manually. How can I create this query?

Upvotes: 1

Views: 321

Answers (1)

Sayse
Sayse

Reputation: 43300

You've complicated things by creating two of the same model.

Start by making a base class and inherit if really needed

class Parent(models.Model):
    house = models.ForiegnKey(House)
    first_name = models.CharField()
    last_name = models.CharField()
    is_head = models.BooleanField()

class Father(Parent):
    pass

class Mother(Parent):
    pass

Then make your query from there

Parent.objects.filter(is_head=True, Q(first_name=form.fname) | Q(last_name=form.lname))

or perhaps (for the house)

self.parent_set.filter(is_head=True, Q(first_name=form.fname) | Q(last_name=form.lname))

Without the base class you'll need a couple queries

def get_head_of_house(self):
    fathers = self.fathers_set.filter(is_head=True, Q(first_name=form.fname) | Q(last_name=form.lname))
    mothers = self.mothers_set.filter(is_head=True, Q(first_name=form.fname) | Q(last_name=form.lname))

    if fathers.exists():
        return fathers  # or perhaps fathers.first()

    if mothers.exists():
        return mothers  # or perhaps mothers.first()

    return None

Upvotes: 1

Related Questions