Search code examples
pythondjangokomodo

Add django model manager code-completion to Komodo


I have been using ActiveState Komodo for a while and while most of the code-completion is spot on it lacks the code completion from Django's model manager.

I have included the Django directory in my PYTHONPATH and get most of the code completion, the notable exception being the models.

Assuming I have a model users I would expect the code users.objects. to show autocomplete options such as all(),count(),filter() etc. however these are added by the model's manager which does so in a seemingly abnormal way.

I am wondering if I can 'force' Komodo to pick up the models.

The model manager looks to be included from the following code (taken from manager.py)

def ensure_default_manager(sender, **kwargs):
"""
Ensures that a Model subclass contains a default manager  and sets the
_default_manager attribute on the class. Also sets up the _base_manager
points to a plain Manager instance (which could be the same as
_default_manager if it's not a subclass of Manager).
"""
cls = sender
if cls._meta.abstract:
    return
if not getattr(cls, '_default_manager', None):
    # Create the default manager, if needed.
    try:
        cls._meta.get_field('objects')
        raise ValueError("Model %s must specify a custom Manager, because it has a field named 'objects'" % cls.__name__)
    except FieldDoesNotExist:
        pass
    cls.add_to_class('objects', Manager())
    cls._base_manager = cls.objects
...

Specifically the last two lines. Is there any way to tell Komodo that <model>.objects = Manager() so the proper code completion is shown?


Solution

  • Probably the easiest way to get this to work seems to be to add the following to the top of models.py:

    from django.db.models import manager
    

    and then under each model add

    objects = manager.Manager()
    

    so that, for example, the following:

    class Site(models.Model):
        name = models.CharField(max_length=200)
        prefix = models.CharField(max_length=1)
        secret = models.CharField(max_length=255)
    
        def __unicode__(self):
            return self.name
    

    becomes

    class Site(models.Model):
        name = models.CharField(max_length=200)
        prefix = models.CharField(max_length=1)
        secret = models.CharField(max_length=255)
    
        objects = manager.Manager()
    
        def __unicode__(self):
            return self.name
    

    This is how you would (explicitly) set your own model manager, and by explicitly setting the model manager (to the default) Kommodo picks up the code completion perfectly.

    Hopefully this will help someone :-)