Login

Tag "manager"

33 snippets

Snippet List

Binding signals to abstract models

Intro ----- I found a question on SO for which Justin Lilly's answer was correct but not as thorough as I'd like, so I ended up working on a simple snippet that shows how to bind signals at runtime, which is nifty when you want to bind signals to an abstract class. Bonus: simple cache invalidation! Question -------- [How do I use Django signals with an abstract model?](http://stackoverflow.com/questions/2692551/how-do-i-use-django-signals-with-an-abstract-model) I have an abstract model that keeps an on-disk cache. When I delete the model, I need it to delete the cache. I want this to happen for every derived model as well. If I connect the signal specifying the abstract model, this does not propagate to the derived models: pre_delete.connect(clear_cache, sender=MyAbstractModel, weak=False) If I try to connect the signal in an init, where I can get the derived class name, it works, but I'm afraid it will attempt to clear the cache as many times as I've initialized a derived model, not just once. Where should I connect the signal? Answer ------ I've created a custom manager that binds a post_save signal to every child of a class, be it abstract or not. This is a one-off, poorly tested code, so beware! It works so far, though. In this example, we allow an abstract model to define CachedModelManager as a manager, which then extends basic caching functionality to the model and its children. It allows you to define a list of volatile keys that should be deleted upon every save (hence the post_save signal) and adds a couple of helper functions to generate cache keys, as well as retrieving, setting and deleting keys. This of course assumes you have a cache backend setup and working properly.

  • managers
  • models
  • cache
  • model
  • manager
  • signals
  • abstract
  • signal
  • contribute_to_class
Read More

Remove a clause from a queryset

I want to create Mixins for QuerySet objects that will by default filter out certain records (e.g. filter out "deleted" records, or filter out "unapproved" records, etc). I'd like those to be separate independent mixins. So in each of those, I override all() to filter out deleted or unapproved, etc. But, I also want to offer a method in the queryset to remove those filters or remove some part of those filters. That's where this code comes in. After some examination of how QuerySets work, this seemed like the simplest method for "undoing" some filter in a queryset

  • hack
  • orm
  • manager
  • mixin
  • queryset
Read More

Custom managers with chainable filters

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: ...>]

  • manager
  • queryset
Read More

Manager for multiple database connections

A Django model manager capable of using different database connections. Inspired by: * [Eric Florenzano](http://www.eflorenzano.com/blog/post/easy-multi-database-support-django/) * [Kenneth Falck](http://kfalck.net/2009/07/01/multiple-databases-and-sharding-with-django) There's a more detailed version in Portuguese in my blog: [Manager para diferentes conexões de banco no Django](http://ricobl.wordpress.com/2009/08/06/manager-para-diferentes-conexoes-de-banco-no-django/)

  • multiple
  • manager
  • database
  • connection
  • databases
  • connections
Read More
Author: rix
  • 0
  • 6

RandomObjectManager

Manager Mixin to implement get_random() in your models. You can override get_objects to tune the queriset To use, define your class: class MyManager(models.Manager, RandomObjectManager): DEFAULT_NUMBER = 5 # I can change that def get_objects(self): return self.filter(active=True) # Only active models plz class MyModel(models.Model): active = models.BooleanField() objects = MyManager() Now you can do: MyModel.objects.get_random()

  • random
  • manager
Read More

SelectRelatedManager

Because select_related() only works on ForeignKeys that are not null or blank, when you are customizing the admin, even if you set "list_select_related=True" you can still end up with way too many querys in the Admin changelist. By adding this code to your model you can decrease the queries dramatically. I found I needed this when I was working with Django apps with a lot of legacy data and I couldn't set the ForeignKey null=False.

  • admin
  • manager
  • select
  • queryset
Read More

Easier chainability with custom QuerySets

Django allows you to specify your own ModelManager with custom methods. However, these methods are chainable. That is, if you have a method on your PersonManager caled men(), you can't do this: Person.objects.filter(birth_date__year=1978).men() Normally, this isn't a problem, however your app may be written to take advantage of the chainability of querysets. For example, you may have an API method which may return a filtered queryset. You would want to call with_counts() on an already filtered queryset. In order to overcome this, we want to override django's QuerySet class, and then make the Manager use this custom class. The only downside is that your functions will not be implemented on the manager itself, so you'd have to call `Person.objects.all().men()` instead of `Person.objects.men()`. To get around this you must also implement the methods on the Manager, which in turn call the custom QuerySet method.

  • model
  • manager
  • queryset
Read More

Tatsypie: additional list endpoints for custom Model's manager methods

Although configuring filtering in TastyPie is possible, it is limited to per-field filters, which are not enough for more complex filtering. If your model implement custom manager methods for complex filters, exposing these methods as TastyPie Resource list endpoints is not an easy task. The ModelResource subclass provided here does this, providing 3 ways of complex filtering: * define querysets for filters directly in the Resource declaration * use Model manager custom method * use QuerySet custom method

  • managers
  • manager
  • custom-manager
  • tastypie
Read More

Model inheritance with content type and inheritance-aware manager

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

  • manager
  • inheritance
Read More

ParentModel and ChildManager for Model Inheritance

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>]

  • model
  • manager
  • queryset
  • inheritance
Read More

Allow filtering and ordering by counts of related query results

I know you're thinking, *what the heck could that title mean?* I often find myself wanting to filter and order by the result of a COUNT(*) of a query using a method similar to the [entry_count example](http://www.djangoproject.com/documentation/db-api/#extra-select-none-where-none-params-none-tables-none). Writing this many times is tedious and hardcoding the table and column names made me cringe, I also wanted the counts to result from more complex queries. This is a method you can add to your custom Manager to do this easily. It's not an ideal syntax, but it's good for the amount of code required. Example: suppose we have some articles we want to filter and order by comments and visit logs to show the most popular... class ArticleManager(models.Manager): count_related = _count_related class Article(models.Model): pub_date = models.DateTimeField(auto_now_add=True) objects = ArticleManager() class Comment(models.Model): article = models.ForeignKey(Article) is_spam = models.BooleanField(default=False) class Visit(models.Model): article = models.ForeignKey(Article) referrer = models.URLField(verify_exists=False) search_query = models.CharField(maxlength=200) Notice how the ArticleManager is given the `count_related` method. Now you can find the most popular like so... Order by non-spam comments: Article.objects.count_related(Comment.objects.filter( is_spam=False)).order_by('-comment__count') Order by incoming non-search-engine links: Article.objects.count_related(Visit.objects.filter( referrer__isnull=False, search_query__isnull=True), 'links').order_by('-links') Order by total visits: Article.objects.count_related(Visit).order_by('-visit__count') Note: Doesn't work if `query` contains joins or for many-to-many relationships, but those could be made to work identically if there's demand.

  • sql
  • model
  • db
  • count
  • manager
Read More

CustomQueryManager

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.

  • models
  • q
  • manager
  • query
  • custom
Read More