Add request.basket_hash for custom caching hooks

To add caching to the basket contents we need a basket hash but we don't
want to load and process all offers. Separate the retrieval of the
basket and make the hash accessible via request.basket_hash
Add comments to better explain basket middleware
Remove unnecessary SQL queries

- Check FK existence in a few places by looking for the ID directly
- Use basket's all_lines method to re-use cached basket when counting
  lines.
Rework basket middleware

- Extract caching logic into one place
- Re-order methods for clarity
- Rename things