简体   繁体   中英

Django, how to set a filter based on a queryset?

I have a queryset given by three different models:

class Sottocategoria(models.Model):
    name = models.CharField('Nome del sottoprodotto', max_length=30)

class A(models.Model):
    codice_commessa=models.ForeignKey()
    prodotto=models.ForeignKey()
    sottocategoria=models.ForeignKey(Sottocategoria)

class B(models.Model):
    quantity=models.ForeignKey()
    price=models.DecimalField()
    sottocategoria=models.ForeignKey(Sottocategoria)

Now I have set the following for loop:

for sottocategoria_id, totale in 
 (B.objects.values_list('sottocategoria__id').annotate(totale=(Sum(F('quantity') * F('price')))):
....

I have the need to filter sottocategoria__id in the models B, that are present in the model A.

Ad example If I have in the model A sottocategoria equal to {'abc','abcd','abcdf'} and model B sottocategoria equal to {'abc','abcd','abcdf', '1234'} , in my for loop I want to filter only {'abc','abcd','abcdf'} .

You can filter with an __in lookup [Django-doc] :

B.objects.filter(
    
).values_list(
    'sottocategoria_id'
).annotate(
    totale=Sum(F('quantity') * F('price'))
)

You also might want to .order_by('sottocategoria_id') , such that if you subscript, you subscript on a sottocategoria_id , not on the primary key of a B object:

B.objects.filter(
    sottocategoria__name__in={'abc','abcd','abcdf'}
).values_list(
    'sottocategoria_id'
).annotate(
    totale=Sum(F('quantity') * F('price'))
)

For example if you look for sottocategoria s that are referenced by an A you can use:

B.objects.filter(
    sottocategoria__in=
).values_list(
    'sottocategoria_id'
).annotate(
    totale=Sum(F('quantity') * F('price'))
).order_by('sottocategoria_id')

for certain databases, like MySQL, it might be better to first materialize the ids:

sottocategoria_ids = list()

B.objects.filter(
    sottocategoria__in=
).values_list(
    'sottocategoria_id'
).annotate(
    totale=Sum(F('quantity') * F('price'))
).order_by('sottocategoria_id')

We can also query from the A model:

sottocategoria_ids = list()

B.objects.filter(
    sottocategoria__in=
).values_list(
    'sottocategoria_id'
).annotate(
    totale=Sum(F('quantity') * F('price'))
).order_by('sottocategoria_id')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM