﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
13313	Custom Default Manager with extra __init__ arguments fails if model is used in a ManyToManyField	CBWhiz@…	nobody	"Suppose I have the following classes:

{{{
class SpecialManager(models.Manager):
    def __init__(self, special_arg):
        self.special_arg=special_arg
    def random_method():
        pass

class SpecialModel(models.Model):
    objects = SpecialManager('hello')
    pass

class InnocentModel(models.Model):
    my_friends = models.ManyToManyField(SpecialModel)
}}}

This is all well and fine, until I actually try to use the model:

{{{
>>> obj = InnocentModel.objects.all()[0]
>>> obj.my_friends
Traceback (most recent call last):
  File ""<console>"", line 1, in <module>
  File ""d:\code\env\src\django\django\db\models\fields\related.py"", line 716, in __get__
    reverse=False
  File ""d:\code\env\src\django\django\db\models\fields\related.py"", line 469, in __init__
    super(ManyRelatedManager, self).__init__()
TypeError: __init__() takes at least 2 arguments (1 given)
}}}

This is because related.py creates a subclass of the manager's default model for relation purposes:

http://code.djangoproject.com/browser/django/trunk/django/db/models/fields/related.py?rev=12908#L706
{{{
        # Dynamically create a class that subclasses the related
        # model's default manager.
        rel_model=self.field.rel.to
        superclass = rel_model._default_manager.__class__
        RelatedManager = create_many_related_manager(superclass, self.field.rel)

        manager = RelatedManager(
            model=rel_model,
            core_filters={'%s__pk' % self.field.related_query_name(): instance._get_pk_val()},
            instance=instance,
            symmetrical=self.field.rel.symmetrical,
            source_field_name=self.field.m2m_field_name(),
            target_field_name=self.field.m2m_reverse_field_name(),
            reverse=False
        )
}}}

This manager is then instantiated, and calls super():

http://code.djangoproject.com/browser/django/trunk/django/db/models/fields/related.py?rev=12908#L469

{{{
465 	    class ManyRelatedManager(superclass):
466 	        def __init__(self, model=None, core_filters=None, instance=None, symmetrical=None,
467 	                join_table=None, source_field_name=None, target_field_name=None,
468 	                reverse=False):
469 	            super(ManyRelatedManager, self).__init__()
}}}

And because this super() is now calling the custom manager's __init__ without passing in any parameters, we get the traceback above.

So, a few questions:

1. Is this a documentation error? Should managers not take __init__ paramaters?

2. You'll notice I don't have use_for_related_fields specified on my manager. According to the documentation ( http://docs.djangoproject.com/en/dev/topics/db/managers/#using-managers-for-related-object-access ) django should use the default manager, right?"	Bug	new	Database layer (models, ORM)	dev	Normal		ManyToManyField, Manager	tomasz.zielinski@…	Accepted	0	0	0	0	0	0
