Try adding parentheses to explicitly specify your grouping? As you already figured out, multiple params to filter() are just joined via AND in the underlying SQL.
Originally you had this for the filter:
[...].filter(
Q(hide=False) & Q(deleted=False),
Q(stock=False) | Q(quantity__gte=1))
If you wanted (A & B) & (C | D) then this should work:
[...].filter(
Q(hide=False) & Q(deleted=False) &
(Q(stock=False) | Q(quantity__gte=1)))