2

What i want to do is when some model use my field, it will automaticaly add custom manager to that model.

As far as i know, contibute_to_class provide such functionality

class MyCustomField(CharField):
    def contribute_to_class(self, cls, name):
        super(MyCustomField, self).contribute_to_class(cls, name)
        setattr(cls, 'custom_manager', CustomManager())

The problem is that in my custom manager i use self.model._default_manager to do queries on default manager but when i try to do it, django says AttributeError: 'NoneType' object has no attribute '_default_manager'

If i dont use contribute_to_class and write custom manager iside my model class, it works as expected. What can be the problem?

user20955
  • 2,552
  • 4
  • 24
  • 23

2 Answers2

4

Managers, just like Fields, have a contribute_to_class method, and if you don't call it they won't be set up properly. The correct way to call it is by using Model.add_to_class:

class MyCustomField(CharField):
    def contribute_to_class(self, cls, name):
        super(MyCustomField, self).contribute_to_class(cls, name)
        cls.add_to_class('custom_manager', CustomManager())
Carl Meyer
  • 122,012
  • 20
  • 106
  • 116
1
class MyCustomField(CharField):
    def contribute_to_class(self, cls, name):
        super(MyCustomField, self).contribute_to_class(cls, name)
        manager = CustomManager()
        manager.model = cls
        setattr(cls, 'custom_manager', manager)
user20955
  • 2,552
  • 4
  • 24
  • 23
  • Setting manager.model manually is hacky and fragile. That is only part of what Manager.contribute_to_class does - the real solution is to ensure Manager.contribute_to_class is called properly. – Carl Meyer Mar 04 '09 at 16:02