Opened 17 years ago

Closed 17 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: dev
Severity: Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

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 by Michael Radziej <mir@…>, 17 years ago

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 by Alex Dedul, 17 years ago

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

django.db.models.AdminOptions.__init__()

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 by Michael Radziej <mir@…>, 17 years ago

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

comment:4 by Alex Dedul, 17 years ago

Here we go. Test case 1:

class KnowledgeBaseCategoryManager(models.Manager):
    def get_query_set(self):
        return super(KnowledgeBaseCategoryManager, self).get_query_set().\
                   filter(name='test')

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):
        return self.name

>>> 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):
        return self.name

>>> 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 by Michael Radziej <mir@…>, 17 years ago

Component: DocumentationAdmin interface
Owner: changed from Jacob to Adrian Holovaty
Triage Stage: UnreviewedAccepted

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 by James Bennett, 17 years ago

Resolution: fixed
Status: newclosed

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