-
First attempt - get product by primary key:
-
ProductRepository
is stateless, use static methods. Usage now looks like: -
It turns out I need a 'get by slug' too:
-
In a web context, I need to limit according to user because not all products are public yet:
-
Need some list APIs as well as individual:
-
And to limit by user sometimes:
-
Need to limit to certain brands, for both list and individual. Now I've got:
ProductRepository.get_by_pk(pk) ProductRepository.get_by_slug(slug) ProductRepository.get_by_pk_for_user(pk, user) ProductRepository.get_by_slug_for_user(slug, user) ProductRepository.get_by_pk_for_brand(pk, brand) ProductRepository.get_by_slug_for_brand(slug, brand) ProductRepository.get_by_pk_for_user_for_brand(pk, user, brand) ProductRepository.get_by_slug_for_user_for_brand(slug, user, brand) ProductRepository.get_all() ProductRepository.get_all_for_user(user) ProductRepository.get_all_for_brand(brand) ProductRepository.get_all_for_user_for_brand(user, brand)
-
Aargh! Refactor:
-
Need paging:
-
But have to specify ordering if paging is to work:
-
Hmm, performance - sometimes I need to fetch other things at the same time:
-
Hmm, my related things also need related things at the same time:
-
Extra flag needed to only show products that are in stock:
-
Fetch the products in user's basket only:
-
Hmm, I have a lot of parameters now:
-
Idea 1 -
Filter
object:
-
Idea 2 - switch to a Fluent interface:
-
Advanced ordering:
-
Finishing touches -
[x:y]
slicing: -
Enlightenment:
Postscript
For those who don't know the context, I'm suggesting you should just use Custom QuerySets as your “service layer”, instead of a hand-coded repository pattern. See also Against service layers in Django.
Also, it's worth noting that the evolution of QuerySets in Django itself wasn't so different from some of these steps.