Search code examples
pythondjangoormdjango-querysetset-theory

I want to use the django ORM to get a complement from two tables


I aready have checked this question Getting complement of queryset. But, it didn't work. It seems like it's only extracting one field in the result.

I have the following two tables:

table A

   001 a 
   002 b
   003 C

table B

   001 a
   002 b
   003 c
   004 d
   005 e

My gaol is get the complement like this:

complement

   004 d
   005 e

How to use the ORM to get this result?

the models

class WordBase(models.Model):
    number  = models.SlugField(primary_key=True)
    word    = models.CharField(max_length=128)
    belong  = models.CharField(max_length=128)
    mean    = models.TextField()
    example = models.TextField()
class PersonalRecord(models.Model):
    user = models.ForeignKey(User)
    book = models.CharField(max_length=128)
    number =  models.CharField(max_length=128)
    begtime= models.CharField(max_length=128)
    endtime = models.CharField(max_length=128,blank=True,)
    lasttime = models.CharField(max_length=128,blank=True,)
    times = models.IntegerField()
    status = models.IntegerField()

Solution

  • The answer in the link you provided should be correct. Basically what you need to do is exclude set A from set B.

    setA = MyModel.objects.filter(…)  # Query for items belonging in set A
    setB = MyModel.objects.filter(…)  # Query for items belonging in set B
    
    # setA and setB are QuerySets, ans as such does not query the database
    # until the data is actually needed. Thus you can just add further
    # delimitations. The below lines does the same thing, somewhat differently.
    
    complement = setB.objects.exclude(pk__in=[o.id for o in setA])
    complement = setB.objects.exclude(pk__in=setA.values_list('pk', flat=True))
    

    As you can see what you need to do is exclude from setB any objects who's pk is in the specified list. [o.id for o in setA] and setA.values_list('pk', flat=True) are two different ways of computing such a list from the previously created query sets (which both hits the database in order to construct the list, obviously).