Opened 9 years ago

Closed 8 years ago

#3416 closed (fixed)

Model API documentation section 'Modifying initial Manager QuerySets' misleads about Admin behaviour

Reported by: Alex Dedul Owned by: nobody
Component: contrib.admin Version: master
Severity: Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:


It says:

If you use custom Manager objects, take note that the first Manager Django encounters 
(in order by which they're defined in the model) has a special status. Django interprets 
the first Manager defined in a class as the "default" Manager. Certain operations -- such
as Django's admin site -- use the default Manager to obtain lists of objects, so it's 
generally a good idea for the first Manager to be relatively unfiltered.

But if you have your custom manager in a model even called 'objects' admin anyway will display all records from model regardless specified custom manager. The only way i found to tell admin to use custom manager is to use 'manager' attribute in inner Admin class in a model. So i guess reference to admin should be removed from here for now and 'manager' attribute of inner Admin class documented instead.

Change History (6)

comment:1 Changed 9 years ago by Michael Radziej <mir@…>

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

Now--did you call the model 'objects' or the custom manager? If the latter, does the situation change if you rename it from "objects" to something else?

comment:2 Changed 9 years ago by Alex Dedul

I'm not trying to use custom manager directly in the code, but to tell admin app to use it(to prefilter records in change list). And whatever i call custom manager in a model 'objects' or 'test_manager' or something else it has no effect on admin's change list.

One more thing - tried with custom manager to see values of foreign key on a change form and here it works correctly displaying records from custom manager and not using default one with all records. So it seems it boils down to


and to this line:

        self.manager = manager or Manager()

where manager is an attribute(undocumented) you can set on inner Admin class and Manager() is a default manager with all records.

So as for me its worth mentioning in docs about this hidden 'manager' attribute and say that model's custom managers is not used in admin's change lists(if we reference admin app in that 'Modifying initial Manager QuerySets' section).

comment:3 Changed 9 years ago by Michael Radziej <mir@…>

I think it should work without using the "hidden manager attribute". Can you please post your model and the manager?

comment:4 Changed 9 years ago by Alex Dedul

Here we go. Test case 1:

class KnowledgeBaseCategoryManager(models.Manager):
    def get_query_set(self):
        return super(KnowledgeBaseCategoryManager, self).get_query_set().\

class KnowledgeBaseCategory(models.Model):
    name = models.CharField(maxlength=100, unique=True)

    class Meta:
        verbose_name_plural = 'Knowledge Base Categories'
        ordering = ('name', )

    class Admin:
        search_fields = ('name',)
        manager = KnowledgeBaseCategoryManager()

    def __str__(self):

>>> KnowledgeBaseCategory.objects.all()
[<KnowledgeBaseCategory: test>, <KnowledgeBaseCategory: test2>]

KnowledgeBaseCategory has 2 records with name 'test' and 'test2', but in admin's change list there is only one record with name 'test' because of manager attribute of inner Admin class.

Test case 2:

# KnowledgeBaseCategoryManager is the same

class KnowledgeBaseCategory(models.Model):
    name = models.CharField(maxlength=100, unique=True)
    test_manager = KnowledgeBaseCategoryManager()

    class Meta:
        verbose_name_plural = 'Knowledge Base Categories'
        ordering = ('name', )

    class Admin:
        search_fields = ('name',)

    def __str__(self):

>>> KnowledgeBaseCategory.test_manager.all()
[<KnowledgeBaseCategory: test>]

Here is custom test_manager returns only 1 record 'test' as expected, but in admin's change list both 'test' and 'test2' records are displayed.

comment:5 Changed 9 years ago by Michael Radziej <mir@…>

  • Component changed from Documentation to Admin interface
  • Owner changed from jacob to adrian
  • Triage Stage changed from Unreviewed to Accepted

Thanks! I see this as a bug in the admin. I made these observations with your second testcase:

  • As you described, the admin shows both objects
  • When I click on 'test2', I get a 404.
  • In the shell, there is no KnowledgeBaseCategory.objects manager at all
  • In the shell, I see that models.KnowledgeBaseCategory._meta.admin.manager is the generic <django.db.models.manager.Manager object at 0xb759c20c>

I suppose that something does not pick up that _meta.admin.manager should be set to the custom manager.

comment:6 Changed 8 years ago by ubernostrum

  • Resolution set to fixed
  • Status changed from new to closed

This has been fixed in newforms-admin, where _meta.admin.manager no longer exists as of [4342].

Note: See TracTickets for help on using tickets.
Back to Top