How to ORM filter a query with parameter list exactly?

Question:

I have a query filter

query_1 = Model.objects.filter(param = param)

I need to filter this list to another ORM and return true or flase only if all the data in the query_1 is in the second query.
Like,

query_2 = AnotherModel.objects.filter(field__in=query_1)

return True only if all the objects in the query_1 list is in the query_2.

Asked By: surya raj

||

Answers:

I don’t think it can be done using only ORM. If field is foreignkey to Model:

def my_func(param):
  list_of_ids_1 = Model.objects.filter(param = param).values_list('id', flat=True)
  list_of_ids_2 = AnotherModel.objects.filter(field__in=list_of_ids_1).values_list('field_id', flat=True).distinct()

  return len(list_of_ids_1) == len(list_of_ids_2)
Answered By: Waldemar Podsiadło

Lets assume Model, AnotherModel are like this

class Model(models.Model):
    param=models.CharField(...)
    ...

class AnotherModel(models.Model);
    field = models.ForeignKey(Model, on_delete=...)  
    ...  
    

Then the following query will return only those Model which have corresponding AnotherModel

result = Model.objects.filter(param=param, anothermodel__isnull=False)

but if you want to check the filter(param=param) result if there is any model which is not present in AnotherModel, you have to do it manually

exists = true
query_1 = Model.objects.filter(param = param)
for model in query_1:
    if not AnotherModel.objects.filter(field=model).exists():
        exists = false
        break

# if exists is true that means all of the query_1 obj is there in AnotherModel 
Answered By: shourav

You can check if there is any Model for which there is no AnotherModel with:

not Model.objects.filter(anothermodel=None).exists()

if the query returns True then not … will thus return False and this means that all Models are referenced by AnotherModel and vice versa.

Answered By: Willem Van Onsem
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.