I think that you are missing my point with Q-objects. Your manager only rewrites kwargs passed to filter and exclude, it will not rewrite Q objects that are passed in directly. With Q objects i mean django.db.models.Q: http://docs.djangoproject.com/en/dev/topics/db/queries/#complex-lookups-with-q-objects
If you had another field - foo - on MyModel and wanted all objects that are completed or where foo='bar', you would issue a query that looks something like this:
MyModel.objects.filter(Q(completed=True) | Q(foo='bar'))
You cannot use your rewrite when chaining filters(), since your filter()/exclude() overrides only works on the manager, and not the queryset. This means that MyModel.objects.all().filter(completed=True) will not work either.
I would just use __isnull instead, it does exactly what you want, without going through the hassle of overriding managers, querys and Q objects - and works everywhere.
However, I think your post is interesting and shows some of the potential with being able to subclass and override managers. It is definately a violation of DRY and ugly to have different fields.
Comment
I seeeeeee! When you wrote Q-object I first thought you meant Queryset, not the search thingy.
And now I see what you mean about MyModel.objects.all().filter(completed=True).
I guess I've taken on a principle too strongly that doesn't quite work the Django way.
Parent comment
I think that you are missing my point with Q-objects. Your manager only rewrites kwargs passed to filter and exclude, it will not rewrite Q objects that are passed in directly. With Q objects i mean django.db.models.Q: http://docs.djangoproject.com/en/dev/topics/db/queries/#complex-lookups-with-q-objects If you had another field - foo - on MyModel and wanted all objects that are completed or where foo='bar', you would issue a query that looks something like this: MyModel.objects.filter(Q(completed=True) | Q(foo='bar')) You cannot use your rewrite when chaining filters(), since your filter()/exclude() overrides only works on the manager, and not the queryset. This means that MyModel.objects.all().filter(completed=True) will not work either. I would just use __isnull instead, it does exactly what you want, without going through the hassle of overriding managers, querys and Q objects - and works everywhere. However, I think your post is interesting and shows some of the potential with being able to subclass and override managers. It is definately a violation of DRY and ugly to have different fields.