2

models.py

class Contact(models.Model):
         attributes = GenericRelation(
 AttributeValue,related_query_name='contact',content_type_field='target_content_type',object_id_field='target_object_id')

class AttributeValue(models.Model):
    attribute = models.ForeignKey(Attribute, related_name="attribute")

    # the object instance we are associating this attribute to
    target_content_type = models.ForeignKey(ContentType, related_name="attribute_value_target_content_type",
                                            on_delete=models.CASCADE, blank=True, null=True)
    target_object_id = models.PositiveIntegerField(blank=True, null=True, db_index=True)
    target = GenericForeignKey('target_content_type', 'target_object_id')

class Attribute(models.Model):
    name = CHarFIeld()

I want to get all the contacts that follow both the conditions below

  1. Have an AttributeValue model object in attributes field with attributes__attribute__name = 'crop_name' and attributes__value='groundnut'
  2. Have an AttributeValue model object in attributes field with attributes__attribute__name = 'crop_season' and attributes__value='winter'

One way to achieve this is mentioned as follows:

Contact.objects.all().filter(Q(attributes__attribute__name='crop_name') & Q(attributes__value='groundnut')).filter(Q(attributes__attribute__name='crop_season') & Q(attributes__value='winter'))

The above mentioned query works fine. But I want to construct a single such query that can be given into .filter()

i.e. something like

Contact.objects.filter(query)

I tried doing something like

Contact.objects.filter(Q(Q(attributes__attribute__name='crop_name') & Q(attributes__value='groundnut'))& Q(Q(attributes__attribute__name='crop_season') & Q(attributes__value='winter')))

Expecting that query would respect the braces, but it doesn't like that i guess

P.S. I am using django(1.11.4) + postgres(9.5.7) combination

Varsha
  • 86
  • 4
  • If your idea is to filter an arbitrary number of Q statements together, why not build the Q statements separately (see https://stackoverflow.com/q/852414/199754) and then iterator through them one by one in a loop i.e. for qstmt in statements: contacts = contacts.filter(qstmt) – Neil Mar 19 '18 at 12:53
  • Its not really to filter number of arbitrary number of Q's together. The query I mentioned above i.e. **Contact.objects.filter(Q(Q(attributes__attribute__name='crop_name') & Q(attributes__value='groundnut'))& Q(Q(attributes__attribute__name='crop_season') & Q(attributes__value='winter')))** , I dont get the desired results which i am looking for. So even when I dynamically construct Q object the ultimate object will end up being same as what I gave as input in **.filter()**. Maybe I am constructing an incorrect Q in this case. I am looking for suggestions on what would be right query look like – Varsha Mar 19 '18 at 13:01

0 Answers0