Django-Abfragefilter, der UND und ODER mit Q-Objekten kombiniert, gibt nicht die erwarteten Ergebnisse zurück
Ich versuche, AND und OR in einem Filter mithilfe von Q-Objekten zu kombinieren. Es sieht so aus benimm dich wie ein UND. Dies bezieht sich auf den vorherigen Kommentar, der in derselben Abfrage und nicht als Unterabfrage ausgeführt wird.
Was ist die richtige Art, mit Django umzugehen?
models.py
class Type(models.Model):
name = models.CharField(_('name'), max_length=100)
stock = models.BooleanField(_('in stock'), default=True)
hide = models.BooleanField(_('hide'), default=False)
deleted = models.BooleanField(_('deleted'), default=False)
class Item(models.Model):
barcode = models.CharField(_('barcode'), max_length=100, blank=True)
quantity = models.IntegerField(_('quantity'), default=1)
type = models.ForeignKey('Type', related_name='items', verbose_name=_('type'))
views.py
def hire(request):
categories_list = Category.objects.all().order_by('sorting')
types_list = Type.objects.annotate(quantity=Sum('items__quantity')).filter(
Q(hide=False) & Q(deleted=False),
Q(stock=False) | Q(quantity__gte=1))
return render_to_response('equipment/hire.html', {
'categories_list': categories_list,
'types_list': types_list,
}, context_instance=RequestContext(request))
Resultierende SQL-Abfrage
SELECT "equipment_type"."id" [...] FROM "equipment_type" LEFT OUTER JOIN
"equipment_subcategory" ON ("equipment_type"."subcategory_id" =
"equipment_subcategory"."id") LEFT OUTER JOIN "equipment_item" ON
("equipment_type"."id" = "equipment_item"."type_id") WHERE
("equipment_type"."hide" = False AND "equipment_type"."deleted" = False )
AND ("equipment_type"."stock" = False )) GROUP BY "equipment_type"."id"
[...] HAVING SUM("equipment_item"."quantity") >= 1
expected SQL query
SELECT
*
FROM
equipment_type
LEFT JOIN (
SELECT type_id, SUM(quantity) AS qty
FROM equipment_item
GROUP BY type_id
) T1
ON id = T1.type_id
WHERE hide=0 AND deleted=0 AND (T1.qty > 0 OR stock=0)
BEARBEITE: Ich habe die erwartete SQL-Abfrage hinzugefügt (ohne den Join für equipment_subcategory)