Active / Inactive model manager
Used for models with active_date and inactive_date. Adds an "active" filter to get only active items
- model
- manager
- active
- inactive
Used for models with active_date and inactive_date. Adds an "active" filter to get only active items
First version Apr 9 09
This is an improvement on [snippet 984](http://www.djangosnippets.org/snippets/984/). Read it's description and [this blog post](http://zerokspot.com/weblog/2008/08/13/genericforeignkeys-with-less-queries/) for good explanations of the problem this solves. Unlike snippet 984, this version is able to handle multiple generic foreign keys, generic foreign keys with nonstandard ct_field and fk_field names, and avoids unnecessary lookups to the ContentType table. To use, just assign an instance of GFKManager as the objects attribute of a model that has generic foreign keys. Then: MyModelWithGFKs.objects.filter(...).fetch_generic_relations() The generic related items will be bulk-fetched to minimize the number of queries.
This is the approach I've taken to access instances of child models from their parent. Functionally it's very similar to snippets [1031](http://www.djangosnippets.org/snippets/1031/) and [1034](http://www.djangosnippets.org/snippets/1034/), but without the use of `django.contrib.contenttypes`. Usage: class Post(ParentModel): title = models.CharField(max_length=50) objects = models.Manager() children = ChildManager() def __unicode__(self): return self.title def get_parent_model(self): return Post class Article(Post): text = models.TextField() class Photo(Post): image = models.ImageField(upload_to='photos/') class Link(Post): url = models.URLField() In this case, the `Post.children` manager will return a queryset containing instances of the appropriate child model, rather than instances of `Post`. >>> Post.objects.all() [<Post: Django>, <Post: Make a Tumblelog>, <Post: Self Portrait>] >>> Post.children.all() [<Link: Django>, <Article: Make a Tumblelog>, <Photo: Self Portrait>]
inspired by crucialfelix's [inheritance hack](http://www.djangosnippets.org/snippets/1031/), which was a far better method of fetching a model's subclassed version from an instance than my own, i decided to bake his snippet in to my own inheritance hack, which i think benefits both. the result is a query set that returns subclassed instances per default. So - in the snippet's example, querying `Meal.objects.all()[0]` will return a salad object, if that instance of Meal happens to be the parent of a Salad instance. To my mind this is closer to the 'intuitive' way for a query set on an inheriting model to behave. **Updated:** added subclassing behaviour for the iterator access as well. **Updated:** incorporated carljm's feedback on inheritance
This is a simple manager that offers one additional method called `relate`, which fetches generic foreign keys (as referenced by `content_type` and `object_id` fields) without requiring one additional query for each contained element. Basically, when working with generic foreign keys (and esp. in the usecase of having something like a tumblelog where you use an additional model just to have a single sorting point of multiple other models), don't do something like `result = StreamItem.objects.select_related()` but just fetch the content type with `result = StreamItem.objects.select_related('content_type')`, otherwise you will end up with first one query for the list of StreamItems but then also with one additional query for each item contained in this resultset. When you now combine the latter call with `result = StreamItem.gfkmanager.relate(result)`, you will just get the one query for the item list + one query for each content type contained in this list (if the models have already been cached). For further details, please read [this post](http://zerokspot.com/weblog/2008/08/13/genericforeignkeys-with-less-queries/) on my blog.
When you're using Django model inheritance, sometimes you want to be able to get objects of the base class that aren't instances of any of the subclasses. You might expect the obvious way of doing this, `SuperModel.objects.filter(submodel__isnull=True)`, to work, but unfortunately it doesn't. (Neither does `SuperModel.objects.filter(submodel__supermodel_ptr=None)`, or any other convoluted way I could think of doing it.) Here's a nicer approach for doing this. [The blog entry is here.](http://sciyoshi.com/blog/2008/aug/07/custom-django-manager-excludes-subclasses/)
A `models.Manager` subclass that helps to remove some of the boilerplate involved in creating managers from certain queries. Usually, a manager would be created by doing this: class MyManager(models.Manager): def get_query_set(self): return super(MyManager, self).get_query_set().filter(query=blah) Other managers may return other query sets, but this is especially useful as one may define queries on a table which would be used a lot. Since the only part that ever changes is the `query=blah` set of keyword arguments, I decided to abstract that into a class which, besides taking the repetition out of manager definition, allows them to be and'd and or'd in a manner similar to the `Q` objects used for complex database queries. `CustomQueryManager` instances may be defined in one of two ways. The first, more laborious but reusable manner, is to subclass it, like so: class MyManager(CustomQueryManager): query = Q(some=query) Then, `MyManager` is instantiated with no arguments on a model, like normal managers. This allows a query to be reused without extra typing and copying, and keeps code DRY. Another way to do this is to pass a `Q` object to the `__init__` method of the `CustomQueryManager` class itself, on the model. This would be done like so: class MyModel(models.Model): field1 = models.CharField(maxlength=100) field2 = models.PositiveIntegerField() my_mgr = CustomQueryManager(Q(field1='Hello, World')) This should mainly be used when a query is only used once, on a particular model. Either way, the definition of `__and__` and `__or__` methods on the `CustomQueryManager` class allow the use of the `&` and `|` operators on instances of the manager and on queries. For example: class Booking(models.Model): start_date = models.DateField() end_date = models.DateField() public = models.BooleanField() confirmed = models.BooleanField() public_bookings = CustomQueryManager(Q(public=True)) private_bookings = public_bookings.not_() confirmed_bookings = CustomQueryManager(Q(confirmed=True)) public_confirmed = public_bookings & confirmed_bookings public_unconfirmed = public_bookings & confirmed_bookings.not_() public_or_confirmed = public_bookings | confirmed_bookings public_past = public_bookings & Q(end_date__lt=models.LazyDate()) public_present = public_bookings & Q(start_date__lte=models.LazyDate(), end_date__gte=models.LazyDate()) public_future = public_bookings & Q(start_date__gt=models.LazyDate()) As you can see, `CustomQueryManager` instances can be manipulated much like `Q` objects, including combination, via `&` (and) and `|` (or), with other managers (currently only other `CustomQueryManager` instances) and even `Q` objects. This makes it easy to define a set of prepared queries on the set of data represented by a model, and removes a lot of the boilerplate of usual manager definition.
This manager is intended for use with models with publication and/or expiration dates. Objects will be retrieved only if their publication and/or expiration dates are within the current date. Use is very simple: class ExampleModel(models.Model): publish_date = models.DateTimeField() expire_date = models.DateTimeField(blank=True, null=True) objects = models.Manager() actives = ActiveManager(from_date='publish_date', to_date='expire_date') ExampleModel.actives.all() # retrieve active objects according to the current date The manager works correctly with nullable date fields. A null publication date means "*always published (until expiration date)*" and a null expiration date means "*never expires*". Most models should define the `objects` manager as the default manager, because otherwise out of date objects won't appear in the admin app.
Sometimes you need to prevent concurrent access to update/calculate some properties right. Here is (MySQL) specific example to lock one table with new object manager functions.
RowCacheManager is a model manager that will try to fetch any 'get' (i.e., single-row) requests from the cache. ModelWithCaching is an abstract base model that does some extra work that you'll probably want if you're using the RowCacheManager. So to use this code, you just need to do two things: First, set objects=RowCacheManager() in your model definition, then inherit from ModelWithCaching if you want the invalidation for free. If you are unusually brave, use the metaclass for ModelWithCaching and you won't even need the "objects=RowCacheManager()" line.
An easy way to add custom methods to the QuerySet used by a Django model. See [simonwillison.net/2008/May/1/orm/](http://simonwillison.net/2008/May/1/orm/) for an in-depth explanation.
The Django docs show us how to give models a custom manager. Unfortunately, filter methods defined this way cannot be chained to each other or to standard queryset filters. Try it: class NewsManager(models.Manager): def live(self): return self.filter(state='published') def interesting(self): return self.filter(interesting=True) >>> NewsManager().live().interesting() AttributeError: '_QuerySet' object has no attribute 'interesting' So, instead of adding our new filters to the custom manager, we add them to a custom queryset. But we still want to be able to access them as methods of the manager. We could add stub methods on the manager for each new filter, calling the corresponding method on the queryset - but that would be a blatant DRY violation. A custom `__getattr__` method on the manager takes care of that problem. And now we can do: >>> NewsManager().live().interesting() [<NewsItem: ...>]
I had a problem: too many fetches from the DB. So, how to reduce load on the database without major changes to the code? Cache Manager is the answer. I've managed to reduce number of DB hits as much as 80% in some cases (dictionaries, complex relations). It is using standard cache mechanisms. I'm using it with mathopd. This is a very simple solution, instead of standard Manager, put this in your model definition as: `objects = CacheManager()` Then everythere elase in the code instead of all() or get(...) call all_cached() or get_cached(). I've kept original methods intact, to have an dual access, when you really, really must have frest data from the DB, and you can't wait for cache to expire. This is much easier to work with, then manually getting fetched data from the cache.No change to your existing code 9except model) and voila! Additionally if you have some data, you would like to store with your serialized object (e.g. related data, dynamic dictionaries), you can do this in the model method '_init_instance_cache'). Drop me an email if you find this useful. :)
Provides the method from_related_ids, which lets you select some objects by providing a list of related ids (The huge difference to __in is that the objects have to match al of the ids, not only one) Model Example:: class Article(models.Model): text = models.TextField() tags = ManyToManyField('Tag') objects = AllInManager() Usage:: Article.objects.from_related_ids((1,2,3,4), 'tags')
33 snippets posted so far.